00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef CGRAPHSLAMENGINE_MR_IMPL_H
00010 #define CGRAPHSLAMENGINE_MR_IMPL_H
00011
00012 namespace mrpt { namespace graphslam {
00013
00014 template<class GRAPH_T>
00015 CGraphSlamEngine_MR<GRAPH_T>::CGraphSlamEngine_MR(
00016 ros::NodeHandle* nh,
00017 const std::string& config_file,
00018 const std::string& rawlog_fname,
00019 const std::string& fname_GT ,
00020 mrpt::graphslam::CWindowManager* win_manager ,
00021 mrpt::graphslam::deciders::CNodeRegistrationDecider<GRAPH_T>* node_reg ,
00022 mrpt::graphslam::deciders::CEdgeRegistrationDecider<GRAPH_T>* edge_reg ,
00023 mrpt::graphslam::optimizers::CGraphSlamOptimizer<GRAPH_T>* optimizer ):
00024 parent_t::CGraphSlamEngine_ROS(
00025 nh,
00026 config_file,
00027 rawlog_fname,
00028 fname_GT,
00029 win_manager,
00030 node_reg,
00031 edge_reg,
00032 optimizer),
00033 m_conn_manager(
00034 dynamic_cast<mrpt::utils::COutputLogger*>(this), nh),
00035 m_nh(nh),
00036 m_graph_nodes_last_size(0),
00037 m_registered_multiple_nodes(false),
00038 cm_graph_async_spinner( 1, &this->custom_service_queue),
00039 m_pause_exec_on_mr_registration(false),
00040 m_sec_alignment_params("AlignmentParameters"),
00041 m_sec_mr_slam_params("MultiRobotParameters"),
00042 m_opts(*this)
00043 {
00044 this->initClass();
00045 }
00046
00047 template<class GRAPH_T>
00048 CGraphSlamEngine_MR<GRAPH_T>::~CGraphSlamEngine_MR() {
00049 MRPT_LOG_DEBUG_STREAM(
00050 "In Destructor: Deleting CGraphSlamEngine_MR instance...");
00051 cm_graph_async_spinner.stop();
00052
00053 for (typename neighbors_t::iterator
00054 neighbors_it = m_neighbors.begin();
00055 neighbors_it != m_neighbors.end();
00056 ++neighbors_it) {
00057 delete *neighbors_it;
00058 }
00059
00060 }
00061
00062 template<class GRAPH_T>
00063 bool CGraphSlamEngine_MR<GRAPH_T>::addNodeBatchesFromAllNeighbors() {
00064 MRPT_START;
00065 using namespace mrpt::graphslam::detail;
00066
00067 bool ret_val = false;
00068 for (const auto& neighbor : m_neighbors) {
00069 if (!isEssentiallyZero(
00070 neighbor->tf_self_to_neighbor_first_integrated_pose) &&
00071 neighbor->hasNewData() &&
00072 neighbor->hasNewNodesBatch(m_opts.nodes_integration_batch_size)) {
00073 bool loc_ret_val = this->addNodeBatchFromNeighbor(neighbor);
00074 if (loc_ret_val) { ret_val = true; }
00075 }
00076 }
00077
00078 return ret_val;
00079 MRPT_END;
00080 }
00081
00082 template<class GRAPH_T>
00083 bool CGraphSlamEngine_MR<GRAPH_T>::
00084 addNodeBatchFromNeighbor(TNeighborAgentProps* neighbor) {
00085 MRPT_START;
00086 ASSERT_(neighbor);
00087 using namespace mrpt::utils;
00088 using namespace mrpt::poses;
00089 using namespace mrpt::math;
00090 using namespace std;
00091
00092
00093 vector_uint nodeIDs;
00094 std::map<mrpt::utils::TNodeID, node_props_t> nodes_params;
00095 neighbor->getCachedNodes(&nodeIDs, &nodes_params, true);
00096
00097
00098
00099
00100 mrpt_msgs::GetCMGraph cm_graph_srv;
00101
00102
00103 for (const auto n : nodeIDs) {
00104 cm_graph_srv.request.nodeIDs.push_back(n);
00105 }
00106
00107 MRPT_LOG_DEBUG_STREAM("Asking for the graph.");
00108 bool res = neighbor->cm_graph_srvclient.call(cm_graph_srv);
00109 if (!res) {
00110 MRPT_LOG_ERROR_STREAM("Service call for CM_Graph failed.");
00111 return false;
00112 }
00113 MRPT_LOG_DEBUG_STREAM("Fetched graph successfully.");
00114 MRPT_LOG_DEBUG_STREAM(cm_graph_srv.response.cm_graph);
00115
00116 GRAPH_T other_graph;
00117 mrpt_bridge::convert(cm_graph_srv.response.cm_graph, other_graph);
00118
00119
00120
00121
00122 MRPT_LOG_WARN_STREAM("Merging new batch from \"" << neighbor->getAgentNs() << "\"..." << endl
00123 << "Batch: " << getSTLContainerAsString(cm_graph_srv.request.nodeIDs));
00124 hypots_t graph_conns;
00125
00126
00127 {
00128 pair<TNodeID, node_props_t> node_props_to_connect = *nodes_params.begin();
00129
00130 hypot_t graph_conn;
00131 constraint_t c;
00132 c.mean = node_props_to_connect.second.pose -
00133 neighbor->last_integrated_pair_neighbor_frame.second;
00134 c.cov_inv.unit();
00135 graph_conn.setEdge(c);
00136
00137 graph_conn.from = INVALID_NODEID;
00138
00139
00140 for (const auto n : this->m_graph.nodes) {
00141 if (n.second.agent_ID_str == neighbor->getAgentNs() &&
00142 n.second.nodeID_loc == neighbor->last_integrated_pair_neighbor_frame.first) {
00143 graph_conn.from = n.first;
00144 break;
00145 }
00146 }
00147 ASSERT_(graph_conn.from != INVALID_NODEID);
00148 graph_conn.to = node_props_to_connect.first;
00149
00150 MRPT_LOG_DEBUG_STREAM("Hypothesis for adding the batch of nodes: " << graph_conn);
00151 graph_conns.push_back(graph_conn);
00152 }
00153
00154 std::map<TNodeID, TNodeID> old_to_new_mappings;
00155 this->m_graph.mergeGraph(
00156 other_graph, graph_conns,
00157 false,
00158 &old_to_new_mappings);
00159
00160
00161
00162
00163 MRPT_LOG_WARN_STREAM("Marking used nodes as integrated - Integrating LSs");
00164 nodes_to_scans2D_t new_nodeIDs_to_scans_pairs;
00165 for (typename vector_uint::const_iterator
00166 n_cit = nodeIDs.begin();
00167 n_cit != nodeIDs.end();
00168 ++n_cit) {
00169
00170
00171 neighbor->nodeID_to_is_integrated.at(*n_cit) = true;
00172
00173
00174
00175 new_nodeIDs_to_scans_pairs.insert(make_pair(
00176 old_to_new_mappings.at(*n_cit),
00177 nodes_params.at(*n_cit).scan));
00178 MRPT_LOG_INFO_STREAM("Adding nodeID-LS of nodeID: "
00179 << "\t[old:] " << *n_cit << endl
00180 << "| [new:] " << old_to_new_mappings.at(*n_cit));
00181 }
00182
00183 this->m_nodes_to_laser_scans2D.insert(
00184 new_nodeIDs_to_scans_pairs.begin(),
00185 new_nodeIDs_to_scans_pairs.end());
00186 edge_reg_mr_t* edge_reg_mr =
00187 dynamic_cast<edge_reg_mr_t*>(this->m_edge_reg);
00188 edge_reg_mr->addBatchOfNodeIDsAndScans(new_nodeIDs_to_scans_pairs);
00189
00190 this->execDijkstraNodesEstimation();
00191 neighbor->resetFlags();
00192
00193
00194 {
00195 TNodeID last_node = *nodeIDs.rbegin();
00196 neighbor->last_integrated_pair_neighbor_frame = make_pair(
00197 last_node,
00198 nodes_params.at(last_node).pose);
00199 }
00200
00201 if (m_pause_exec_on_mr_registration) this->pauseExec();
00202 return true;
00203 MRPT_END;
00204 }
00205
00206 template<class GRAPH_T>
00207 bool CGraphSlamEngine_MR<GRAPH_T>::findTFsWithAllNeighbors() {
00208 MRPT_START;
00209 using namespace mrpt::utils;
00210 using namespace mrpt::math;
00211
00212 if (this->m_graph.nodeCount() < m_opts.inter_group_node_count_thresh) {
00213 return false;
00214 }
00215
00216
00217
00218
00219 this->computeMap();
00220
00221 bool ret_val = false;
00222
00223
00224 for (typename neighbors_t::iterator
00225 neighbors_it = m_neighbors.begin();
00226 neighbors_it != m_neighbors.end();
00227 ++neighbors_it) {
00228
00229
00230
00231 if (!m_neighbor_to_found_initial_tf.at(*neighbors_it)) {
00232
00233 bool loc_ret_val = findTFWithNeighbor(*neighbors_it);
00234 if (loc_ret_val) {
00235 MRPT_LOG_DEBUG_STREAM(
00236 "Updating own cached map after successful node registration...");
00237
00238 this->computeMap();
00239
00240
00241 m_neighbor_to_found_initial_tf.at(*neighbors_it) = true;
00242
00243 ret_val = true;
00244 }
00245 }
00246 }
00247
00248 return ret_val;
00249 MRPT_END;
00250 }
00251
00252 template<class GRAPH_T>
00253 bool CGraphSlamEngine_MR<GRAPH_T>::
00254 findTFWithNeighbor(TNeighborAgentProps* neighbor) {
00255 MRPT_START;
00256 using namespace mrpt::slam;
00257 using namespace mrpt::math;
00258 using namespace mrpt::poses;
00259 using namespace mrpt::utils;
00260 using namespace mrpt::maps;
00261 using namespace mrpt::graphslam::detail;
00262
00263 bool ret_val = false;
00264
00265 vector_uint neighbor_nodes;
00266 std::map<mrpt::utils::TNodeID, node_props_t> nodes_params;
00267 neighbor->getCachedNodes(&neighbor_nodes, &nodes_params, false);
00268 if (neighbor_nodes.size() < m_opts.inter_group_node_count_thresh ||
00269 !neighbor->hasNewData()) {
00270 return false;
00271 }
00272
00273
00274
00275
00276 COccupancyGridMap2DPtr neighbor_gridmap = neighbor->getGridMap();
00277 CGridMapAligner gridmap_aligner;
00278 gridmap_aligner.options = m_alignment_options;
00279
00280 CGridMapAligner::TReturnInfo results;
00281 float run_time = 0;
00282
00283 CPosePDFGaussian init_estim;
00284 init_estim.mean = neighbor->tf_self_to_neighbor_first_integrated_pose;
00285 this->logFmt(LVL_INFO,
00286 "Trying to align the maps, initial estimation: %s",
00287 init_estim.mean.asString().c_str());
00288
00289
00290
00291
00292
00293 const CPosePDFPtr pdf_tmp = gridmap_aligner.AlignPDF(
00294 this->m_gridmap_cached.pointer(), neighbor_gridmap.pointer(),
00295 init_estim,
00296 &run_time, &results);
00297 this->logFmt(LVL_INFO, "Elapsed Time: %f", run_time);
00298 CPosePDFSOGPtr pdf_out = CPosePDFSOG::Create();
00299 pdf_out->copyFrom(*pdf_tmp);
00300
00301 CPose2D pose_out; CMatrixDouble33 cov_out;
00302 pdf_out->getMostLikelyCovarianceAndMean(cov_out, pose_out);
00303
00304 this->logFmt(LVL_INFO, "%s\n",
00305 getGridMapAlignmentResultsAsString(*pdf_tmp, results).c_str());
00306
00307
00308 if (results.goodness > 0.999 ||
00309 isEssentiallyZero(pose_out)) {
00310 return false;
00311 }
00312
00313
00314
00315
00317
00318
00319
00320
00321 mrpt_msgs::GetCMGraph cm_graph_srv;
00322 typedef mrpt_msgs::GetCMGraphRequest::_nodeIDs_type nodeID_type;
00323 nodeID_type& matched_nodeIDs =
00324 cm_graph_srv.request.nodeIDs;
00325
00326
00327
00328 for (typename vector_uint::const_iterator
00329 n_cit = neighbor_nodes.begin();
00330 n_cit != neighbor_nodes.end();
00331 ++n_cit) {
00332 matched_nodeIDs.push_back(*n_cit);
00333 }
00334
00335 MRPT_LOG_DEBUG_STREAM("Asking for the graph.");
00336 bool res = neighbor->cm_graph_srvclient.call(cm_graph_srv);
00337 if (!res) {
00338 MRPT_LOG_ERROR_STREAM("Service call for CM_Graph failed.");
00339 return false;
00340 }
00341 MRPT_LOG_DEBUG_STREAM("Fetched graph successfully.");
00342 MRPT_LOG_DEBUG_STREAM(cm_graph_srv.response.cm_graph);
00343
00344 GRAPH_T other_graph;
00345 mrpt_bridge::convert(cm_graph_srv.response.cm_graph, other_graph);
00346
00347
00348
00349
00350 MRPT_LOG_WARN_STREAM("Merging graph of \"" << neighbor->getAgentNs() << "\"...");
00351 hypots_t graph_conns;
00352
00353
00354 {
00355 hypot_t graph_conn;
00356 constraint_t c;
00357 c.mean = pose_out;
00358 cov_out.inv(c.cov_inv);
00359 graph_conn.setEdge(c);
00360
00361 graph_conn.from = 0;
00362 graph_conn.to = *neighbor_nodes.begin();
00363
00364 graph_conn.goodness = results.goodness;
00365 graph_conns.push_back(graph_conn);
00366 }
00367
00368 std::map<TNodeID, TNodeID> old_to_new_mappings;
00369 this->m_graph.mergeGraph(
00370 other_graph, graph_conns,
00371 false,
00372 &old_to_new_mappings);
00373
00374
00375
00376
00377 MRPT_LOG_WARN_STREAM("Marking used nodes as integrated - Integrating LSs");
00378 nodes_to_scans2D_t new_nodeIDs_to_scans_pairs;
00379 for (typename vector_uint::const_iterator
00380 n_cit = neighbor_nodes.begin();
00381 n_cit != neighbor_nodes.end();
00382 ++n_cit) {
00383
00384
00385 neighbor->nodeID_to_is_integrated.at(*n_cit) = true;
00386
00387
00388
00389 new_nodeIDs_to_scans_pairs.insert(make_pair(
00390 old_to_new_mappings.at(*n_cit),
00391 nodes_params.at(*n_cit).scan));
00392 MRPT_LOG_INFO_STREAM("Adding nodeID-LS of nodeID: "
00393 << "\t[old:] " << *n_cit << endl
00394 << "| [new:] " << old_to_new_mappings.at(*n_cit));
00395 }
00396
00397 this->m_nodes_to_laser_scans2D.insert(
00398 new_nodeIDs_to_scans_pairs.begin(),
00399 new_nodeIDs_to_scans_pairs.end());
00400 edge_reg_mr_t* edge_reg_mr =
00401 dynamic_cast<edge_reg_mr_t*>(this->m_edge_reg);
00402 edge_reg_mr->addBatchOfNodeIDsAndScans(new_nodeIDs_to_scans_pairs);
00403
00404
00405
00406
00407
00408 MRPT_LOG_WARN_STREAM("Executing Dijkstra..." << endl);
00409 this->execDijkstraNodesEstimation();
00410
00411 neighbor->resetFlags();
00412
00413
00414 neighbor->tf_self_to_neighbor_first_integrated_pose = pose_out;
00415
00416
00417 {
00418 TNodeID last_node = *neighbor_nodes.rbegin();
00419 neighbor->last_integrated_pair_neighbor_frame = make_pair(
00420 last_node,
00421 nodes_params.at(last_node).pose);
00422 }
00423
00424 MRPT_LOG_WARN_STREAM("Nodes of neighbor [" << neighbor->getAgentNs()
00425 << "] have been integrated successfully");
00426
00427 if (m_pause_exec_on_mr_registration) this->pauseExec();
00428 ret_val = true;
00429
00430 return ret_val;
00431 MRPT_END;
00432 }
00433
00434 template<class GRAPH_T>
00435 bool CGraphSlamEngine_MR<GRAPH_T>::_execGraphSlamStep(
00436 mrpt::obs::CActionCollectionPtr& action,
00437 mrpt::obs::CSensoryFramePtr& observations,
00438 mrpt::obs::CObservationPtr& observation,
00439 size_t& rawlog_entry) {
00440 MRPT_START;
00441 using namespace mrpt::graphslam::deciders;
00442 using namespace mrpt;
00443
00444
00445 bool continue_exec = parent_t::_execGraphSlamStep(
00446 action, observations, observation, rawlog_entry);
00447
00448
00449 bool did_register_from_map_merge;
00450 if (!m_opts.conservative_find_initial_tfs_to_neighbors) {
00451 did_register_from_map_merge = this->findTFsWithAllNeighbors();
00452 }
00453 else {
00454 THROW_EXCEPTION("Conservative inter-graph TF computation is not yet implemented.");
00455 }
00456
00457 bool did_register_from_batches = this->addNodeBatchesFromAllNeighbors();
00458 m_registered_multiple_nodes = (did_register_from_map_merge || did_register_from_batches);
00459
00460 if (m_registered_multiple_nodes) {
00461 if (this->m_enable_visuals) {
00462 this->updateAllVisuals();
00463 }
00464 }
00465
00466 return continue_exec;
00467 MRPT_END;
00468 }
00469
00470 template<class GRAPH_T>
00471 void CGraphSlamEngine_MR<GRAPH_T>::initClass() {
00472 using namespace mrpt::graphslam;
00473 using namespace mrpt::utils;
00474 using namespace std;
00475
00476
00477
00478 m_mr_ns = "mr_info";
00479
00480
00481 m_list_neighbors_topic = m_mr_ns + "/" + "neighbors";
00482 m_last_regd_id_scan_topic = m_mr_ns + "/" + "last_nodeID_laser_scan";
00483 m_last_regd_nodes_topic = m_mr_ns + "/" + "last_regd_nodes";
00484 m_cm_graph_service = m_mr_ns + "/" + "get_cm_graph";
00485
00486 this->m_class_name = "CGraphSlamEngine_MR_" + m_conn_manager.getTrimmedNs();
00487 this->setLoggerName(this->m_class_name);
00488 this->setupComm();
00489
00490
00491
00492 std::vector<string> nodes_up;
00493 ros::master::getNodes(nodes_up);
00494
00495
00496 MRPT_LOG_INFO_STREAM("Waiting for master_discovery, master_sync nodes to come up....");
00497 ros::service::waitForService("/master_sync/get_sync_info");
00498 MRPT_LOG_INFO_STREAM("master_discovery, master_sync are available.");
00499
00500 this->m_node_reg->setClassName(
00501 this->m_node_reg->getClassName() + "_" + m_conn_manager.getTrimmedNs());
00502 this->m_edge_reg->setClassName(
00503 this->m_edge_reg->getClassName() + "_" + m_conn_manager.getTrimmedNs());
00504 this->m_optimizer->setClassName(
00505 this->m_optimizer->getClassName() + "_" + m_conn_manager.getTrimmedNs());
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 {
00516 CRegistrationDeciderOrOptimizer_MR<GRAPH_T>* dec_opt_mr =
00517 dynamic_cast<CRegistrationDeciderOrOptimizer_MR<GRAPH_T>*>(this->m_node_reg);
00518
00519 if (dec_opt_mr) {
00520 dec_opt_mr->setCConnectionManagerPtr(&m_conn_manager);
00521 }
00522 }
00523 {
00524 CRegistrationDeciderOrOptimizer_MR<GRAPH_T>* dec_opt_mr =
00525 dynamic_cast<CRegistrationDeciderOrOptimizer_MR<GRAPH_T>*>(this->m_edge_reg);
00526 ASSERT_(dec_opt_mr);
00527 dec_opt_mr->setCConnectionManagerPtr(&m_conn_manager);
00528 dec_opt_mr->setCGraphSlamEnginePtr(this);
00529 }
00530 {
00531 CRegistrationDeciderOrOptimizer_MR<GRAPH_T>* dec_opt_mr =
00532 dynamic_cast<CRegistrationDeciderOrOptimizer_MR<GRAPH_T>*>(this->m_optimizer);
00533 if (dec_opt_mr) {
00534 dec_opt_mr->setCConnectionManagerPtr(&m_conn_manager);
00535 }
00536 }
00537
00538 if (this->m_enable_visuals) {
00539
00540 this->m_win_manager->assignTextMessageParameters(
00541 &m_offset_y_nrd,
00542 &m_text_index_nrd);
00543 this->m_win_manager->addTextMessage(this->m_offset_x_left, -m_offset_y_nrd,
00544 mrpt::format("NRD: %s", this->m_node_reg->getClassName().c_str()),
00545 TColorf(0,0,0),
00546 m_text_index_nrd);
00547
00548
00549 this->m_win_manager->assignTextMessageParameters(
00550 &m_offset_y_erd,
00551 &m_text_index_erd);
00552 this->m_win_manager->addTextMessage(
00553 this->m_offset_x_left, -m_offset_y_erd,
00554 mrpt::format("ERD: %s", this->m_edge_reg->getClassName().c_str()),
00555 TColorf(0,0,0),
00556 m_text_index_erd);
00557
00558
00559 this->m_win_manager->assignTextMessageParameters(
00560 &m_offset_y_gso,
00561 &m_text_index_gso);
00562 this->m_win_manager->addTextMessage(
00563 this->m_offset_x_left, -m_offset_y_gso,
00564 mrpt::format("GSO: %s", this->m_optimizer->getClassName().c_str()),
00565 TColorf(0,0,0),
00566 m_text_index_gso);
00567
00568
00569 this->m_win_manager->assignTextMessageParameters(
00570 &m_offset_y_namespace,
00571 &m_text_index_namespace);
00572 this->m_win_manager->addTextMessage(
00573 this->m_offset_x_left, -m_offset_y_namespace,
00574 mrpt::format("Agent ID: %s", m_conn_manager.getTrimmedNs().c_str()),
00575 TColorf(0,0,0),
00576 m_text_index_namespace);
00577
00578 }
00579 this->readParams();
00580
00581 this->m_optimized_map_color = m_neighbor_colors_manager.getNextTColor();
00582
00583
00584 cm_graph_async_spinner.start();
00585 }
00586
00587 template<class GRAPH_T>
00588 mrpt::poses::CPose3D CGraphSlamEngine_MR<GRAPH_T>::
00589 getLSPoseForGridMapVisualization(
00590 const mrpt::utils::TNodeID nodeID) const {
00591 MRPT_START;
00592 using namespace mrpt::graphs::detail;
00593
00594
00595
00596
00597 const TMRSlamNodeAnnotations* node_annots = dynamic_cast<const TMRSlamNodeAnnotations*>(
00598 &this->m_graph.nodes.at(nodeID));
00599
00600
00601 TNeighborAgentProps* neighbor = NULL;
00602 this->getNeighborByAgentID(node_annots->agent_ID_str, neighbor);
00603
00604 CPose3D laser_pose;
00605 if (!neighbor) {
00606 laser_pose = parent_t::getLSPoseForGridMapVisualization(nodeID);
00607 }
00608 else {
00609 laser_pose = CPose3D(neighbor->tf_self_to_neighbor_first_integrated_pose);
00610 }
00611 return laser_pose;
00612
00613 MRPT_END;
00614 }
00615
00616 template<class GRAPH_T>
00617 bool CGraphSlamEngine_MR<GRAPH_T>::
00618 getNeighborByAgentID(const std::string& agent_ID_str,
00619 TNeighborAgentProps*& neighbor) const {
00620 MRPT_START;
00621
00622 bool ret= false;
00623 for (auto neighbors_it = m_neighbors.begin();
00624 neighbors_it != m_neighbors.end();
00625 ++neighbors_it) {
00626
00627 if ((*neighbors_it)->getAgentNs() == agent_ID_str) {
00628 ret = true;
00629 neighbor = *neighbors_it;
00630 break;
00631 }
00632 }
00633
00634 return ret;
00635 MRPT_END;
00636 }
00637
00638 template<class GRAPH_T>
00639 void CGraphSlamEngine_MR<GRAPH_T>::usePublishersBroadcasters() {
00640 MRPT_START;
00641 using namespace mrpt_bridge;
00642 using namespace mrpt_msgs;
00643 using namespace std;
00644 using namespace mrpt::math;
00645 using ::operator==;
00646
00647
00648 parent_t::usePublishersBroadcasters();
00649
00650
00651 mrpt_msgs::GraphSlamAgents nearby_slam_agents;
00652 m_conn_manager.getNearbySlamAgents(
00653 &nearby_slam_agents,
00654 true);
00655 m_list_neighbors_pub.publish(nearby_slam_agents);
00656
00657
00658
00659
00660
00661 {
00662 for (GraphSlamAgents::_list_type::const_iterator
00663 it = nearby_slam_agents.list.begin();
00664 it != nearby_slam_agents.list.end();
00665 ++it) {
00666
00667 const GraphSlamAgent& gsa = *it;
00668
00669
00670 const auto search = [gsa](const TNeighborAgentProps* neighbor) {
00671 return (neighbor->agent == gsa);
00672 };
00673 typename neighbors_t::const_iterator neighbor_it = find_if(
00674 m_neighbors.begin(),
00675 m_neighbors.end(), search);
00676
00677 if (neighbor_it == m_neighbors.end()) {
00678
00679 MRPT_LOG_DEBUG_STREAM("Initializing NeighborAgentProps instance for "
00680 << gsa.name.data);
00681 m_neighbors.push_back(new TNeighborAgentProps(*this, gsa));
00682 TNeighborAgentProps* latest_neighbor = m_neighbors.back();
00683 latest_neighbor->setTColor(m_neighbor_colors_manager.getNextTColor());
00684 m_neighbor_to_found_initial_tf.insert(make_pair(
00685 latest_neighbor, false));
00686 latest_neighbor->setupComm();
00687 }
00688 }
00689 }
00690
00691 this->pubUpdatedNodesList();
00692 this->pubLastRegdIDScan();
00693
00694 MRPT_END;
00695 }
00696
00697 template<class GRAPH_T>
00698 bool CGraphSlamEngine_MR<GRAPH_T>::pubUpdatedNodesList() {
00699 MRPT_START;
00700 using namespace mrpt_msgs;
00701
00702
00703
00704 if (this->m_graph_nodes_last_size == this->m_graph.nodes.size()) {
00705 return false;
00706 }
00707 MRPT_LOG_DEBUG_STREAM("Updating list of node poses");
00708
00709
00710 typename GRAPH_T::global_poses_t poses_to_send;
00711 int poses_counter = 0;
00712
00713 NodeIDWithPose_vec ros_nodes;
00714
00715
00716 for (typename GRAPH_T::global_poses_t::const_reverse_iterator
00717 cit = this->m_graph.nodes.rbegin();
00718 (poses_counter <= m_opts.num_last_regd_nodes &&
00719 cit != this->m_graph.nodes.rend());
00720 ++cit) {
00721
00722
00723 if (cit->second.agent_ID_str != m_conn_manager.getTrimmedNs()) {
00724 continue;
00725 }
00726
00727 NodeIDWithPose curr_node_w_pose;
00728
00729 curr_node_w_pose.nodeID = cit->first;
00730 mrpt_bridge::convert(cit->second, curr_node_w_pose.pose);
00731
00732
00733 curr_node_w_pose.str_ID.data = cit->second.agent_ID_str;
00734 curr_node_w_pose.nodeID_loc = cit->second.nodeID_loc;
00735
00736 ros_nodes.vec.push_back(curr_node_w_pose);
00737
00738 poses_counter++;
00739 }
00740
00741 m_last_regd_nodes_pub.publish(ros_nodes);
00742
00743
00744 m_graph_nodes_last_size = this->m_graph.nodeCount();
00745
00746 bool res = false;
00747 if (poses_counter) {
00748 res = true;
00749 }
00750
00751 return res;
00752 MRPT_END;
00753 }
00754
00755 template<class GRAPH_T>
00756 bool CGraphSlamEngine_MR<GRAPH_T>::pubLastRegdIDScan() {
00757 MRPT_START;
00758 using namespace mrpt_msgs;
00759 using namespace mrpt_bridge;
00760
00761
00762
00763
00764
00765
00766
00767 if (!this->m_nodes_to_laser_scans2D.empty() &&
00768 m_nodes_to_laser_scans2D_last_size < this->m_nodes_to_laser_scans2D.size()) {
00769
00770 MRPT_NodeIDWithLaserScan mrpt_last_regd_id_scan =
00771 *(this->m_nodes_to_laser_scans2D.rbegin());
00772
00773
00774
00775 if (!this->isOwnNodeID(mrpt_last_regd_id_scan.first)) {
00776 return false;
00777 }
00778
00779
00780
00781
00782 ASSERT_(mrpt_last_regd_id_scan.second);
00783
00784
00785 mrpt_msgs::NodeIDWithLaserScan ros_last_regd_id_scan;
00786 convert(*(mrpt_last_regd_id_scan.second), ros_last_regd_id_scan.scan);
00787 ros_last_regd_id_scan.nodeID = mrpt_last_regd_id_scan.first;
00788
00789 m_last_regd_id_scan_pub.publish(ros_last_regd_id_scan);
00790
00791
00792 m_nodes_to_laser_scans2D_last_size =
00793 this->m_nodes_to_laser_scans2D.size();
00794
00795 return true;
00796 }
00797 else {
00798 return false;
00799 }
00800
00801
00802 MRPT_END;
00803 }
00804
00805
00806 template<class GRAPH_T>
00807 bool CGraphSlamEngine_MR<GRAPH_T>::isOwnNodeID(
00808 const mrpt::utils::TNodeID nodeID,
00809 const global_pose_t* pose_out) const {
00810 MRPT_START;
00811 using namespace mrpt::graphs::detail;
00812
00813
00814 typename GRAPH_T::global_poses_t::const_iterator global_pose_search =
00815 this->m_graph.nodes.find(nodeID);
00816 ASSERTMSG_(global_pose_search != this->m_graph.nodes.end(),
00817 mrpt::format(
00818 "isOwnNodeID called for nodeID \"%lu\" which is not found in the graph",
00819 static_cast<unsigned long>(nodeID)));
00820
00821
00822 if (pose_out) {
00823 pose_out = &global_pose_search->second;
00824 }
00825
00826 bool res = false;
00827 const TMRSlamNodeAnnotations* node_annots = dynamic_cast<const TMRSlamNodeAnnotations*>(
00828 &global_pose_search->second);
00829 if ((node_annots && node_annots->agent_ID_str == m_conn_manager.getTrimmedNs()) ||
00830 (!node_annots)) {
00831 res = true;
00832 }
00833
00834 return res;
00835
00836 MRPT_END;
00837 }
00838
00839 template<class GRAPH_T>
00840 void CGraphSlamEngine_MR<GRAPH_T>::readParams() {
00841 using namespace mrpt::utils;
00842 using namespace mrpt::slam;
00843
00844 this->readROSParameters();
00845
00846
00847 m_alignment_options.loadFromConfigFileName(this->m_config_fname, m_sec_alignment_params);
00848
00849
00850
00851 m_alignment_options.methodSelection = CGridMapAligner::amModifiedRANSAC;
00852
00853 m_opts.loadFromConfigFileName(this->m_config_fname, m_sec_mr_slam_params);
00854 }
00855
00856 template<class GRAPH_T>
00857 void CGraphSlamEngine_MR<GRAPH_T>::readROSParameters() {
00858
00859
00860 parent_t::readROSParameters();
00861
00862 }
00863
00864 template<class GRAPH_T>
00865 void CGraphSlamEngine_MR<GRAPH_T>::printParams() const {
00866 parent_t::printParams();
00867 m_alignment_options.dumpToConsole();
00868 m_opts.dumpToConsole();
00869 }
00870
00871
00872
00873 template<class GRAPH_T>
00874 void CGraphSlamEngine_MR<GRAPH_T>::setupSubs() { }
00875
00876 template<class GRAPH_T>
00877 void CGraphSlamEngine_MR<GRAPH_T>::setupPubs() {
00878 using namespace mrpt_msgs;
00879 using namespace sensor_msgs;
00880
00881 m_list_neighbors_pub = m_nh->advertise<GraphSlamAgents>(
00882 m_list_neighbors_topic,
00883 this->m_queue_size,
00884 true);
00885
00886
00887
00888 m_last_regd_id_scan_pub = m_nh->advertise<NodeIDWithLaserScan>(
00889 m_last_regd_id_scan_topic,
00890 this->m_queue_size,
00891 true);
00892
00893
00894 m_last_regd_nodes_pub = m_nh->advertise<NodeIDWithPose_vec>(
00895 m_last_regd_nodes_topic,
00896 this->m_queue_size,
00897 true);
00898
00899
00900
00901 }
00902
00903 template<class GRAPH_T>
00904 void CGraphSlamEngine_MR<GRAPH_T>::setupSrvs() {
00905
00906 ros::CallbackQueueInterface* global_queue = m_nh->getCallbackQueue();
00907 m_nh->setCallbackQueue(&this->custom_service_queue);
00908
00909 m_cm_graph_srvserver = m_nh->advertiseService(
00910 m_cm_graph_service,
00911 &CGraphSlamEngine_MR<GRAPH_T>::getCMGraph, this);
00912
00913 m_nh->setCallbackQueue(global_queue);
00914 }
00915
00916 template<class GRAPH_T>
00917 bool CGraphSlamEngine_MR<GRAPH_T>::getCMGraph(
00918 mrpt_msgs::GetCMGraph::Request& req,
00919 mrpt_msgs::GetCMGraph::Response& res) {
00920 using namespace std;
00921 using namespace mrpt::utils;
00922 using namespace mrpt::math;
00923
00924 const size_t min_nodeIDs = 2;
00925
00926 set<TNodeID> nodes_set(req.nodeIDs.begin(), req.nodeIDs.end());
00927 MRPT_LOG_INFO_STREAM("Called the GetCMGraph service for nodeIDs: "
00928 << getSTLContainerAsString(nodes_set));
00929
00930 bool ret_val = false;
00931 if (nodes_set.size() < 2) { }
00932 else {
00933
00934 GRAPH_T mrpt_subgraph;
00935 this->m_graph.extractSubGraph(nodes_set, &mrpt_subgraph,
00936 INVALID_NODEID,
00937 false);
00938 mrpt_bridge::convert(mrpt_subgraph, res.cm_graph);
00939 ret_val = true;
00940 }
00941
00942 return ret_val;
00943 }
00944
00945 template<class GRAPH_T>
00946 void CGraphSlamEngine_MR<GRAPH_T>::setObjectPropsFromNodeID(
00947 const mrpt::utils::TNodeID nodeID,
00948 mrpt::opengl::CSetOfObjectsPtr& viz_object) {
00949 using namespace mrpt::utils;
00950 MRPT_START;
00951
00952
00953 TNeighborAgentProps* neighbor = NULL;
00954 std::string& agent_ID_str = this->m_graph.nodes.at(nodeID).agent_ID_str;
00955 bool is_not_own = getNeighborByAgentID(agent_ID_str, neighbor);
00956
00957 TColor obj_color;
00958 if (!is_not_own) {
00959
00960 obj_color = this->m_optimized_map_color;
00961 }
00962 else {
00963 ASSERT_(neighbor);
00964 obj_color = neighbor->color;
00965 }
00966 viz_object->setColor_u8(obj_color);
00967
00968 MRPT_END;
00969 }
00970
00971
00972 template<class GRAPH_T>
00973 void CGraphSlamEngine_MR<GRAPH_T>::monitorNodeRegistration(
00974 bool registered,
00975 std::string class_name) {
00976 MRPT_START;
00977 using namespace mrpt::utils;
00978
00979 if (m_registered_multiple_nodes) {
00980 MRPT_LOG_ERROR_STREAM("m_registered_multiple_nodes = TRUE!");
00981 m_registered_multiple_nodes = !m_registered_multiple_nodes;
00982 this->m_nodeID_max = this->m_graph.nodeCount()-1;
00983 }
00984 else {
00985 parent_t::monitorNodeRegistration(registered, class_name);
00986 }
00987
00988 MRPT_END;
00989 }
00990
00991 template<class GRAPH_T>
00992 void CGraphSlamEngine_MR<GRAPH_T>::getRobotEstimatedTrajectory(
00993 typename GRAPH_T::global_poses_t* graph_poses) const {
00994 MRPT_START;
00995 ASSERT_(graph_poses);
00996
00997 for (const auto& n : this->m_graph.nodes) {
00998 if (n.second.agent_ID_str == m_conn_manager.getTrimmedNs()) {
00999 graph_poses->insert(n);
01000 }
01001 }
01002
01003 MRPT_END;
01004 }
01005
01006 template<class GRAPH_T>
01007 void CGraphSlamEngine_MR<GRAPH_T>::
01008 getAllOwnNodes(std::set<mrpt::utils::TNodeID>* nodes_set) const {
01009 ASSERT_(nodes_set);
01010 nodes_set->clear();
01011
01012 for (const auto& n : this->m_graph.nodes) {
01013 if (n.second.agent_ID_str == m_conn_manager.getTrimmedNs()) {
01014 nodes_set->insert(n.first);
01015 }
01016 }
01017 }
01018
01019 template<class GRAPH_T>
01020 void CGraphSlamEngine_MR<GRAPH_T>::
01021 getNodeIDsOfEstimatedTrajectory(
01022 std::set<mrpt::utils::TNodeID>* nodes_set) const {
01023 ASSERT_(nodes_set);
01024 this->getAllOwnNodes(nodes_set);
01025 }
01026
01028
01029 template<class GRAPH_T>
01030 CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::TNeighborAgentProps(
01031 CGraphSlamEngine_MR<GRAPH_T>& engine_in,
01032 const mrpt_msgs::GraphSlamAgent& agent_in):
01033 engine(engine_in),
01034 agent(agent_in),
01035 has_setup_comm(false)
01036 {
01037 using namespace mrpt::utils;
01038
01039 nh = engine.m_nh;
01040 m_queue_size = engine.m_queue_size;
01041 this->resetFlags();
01042
01043
01044
01045 this->last_regd_nodes_topic = "/" + agent.topic_namespace.data + "/" +
01046 engine.m_last_regd_nodes_topic;
01047 this->last_regd_id_scan_topic = "/" + agent.topic_namespace.data + "/" +
01048 engine.m_last_regd_id_scan_topic;
01049 this->cm_graph_service = "/" + agent.topic_namespace.data + "/" +
01050 engine.m_cm_graph_service;
01051
01052 engine.logFmt(LVL_DEBUG,
01053 "In constructor of TNeighborAgentProps for topic namespace: %s",
01054 agent.topic_namespace.data.c_str());
01055
01056
01057 gridmap_cached = mrpt::maps::COccupancyGridMap2D::Create();
01058 COccupancyGridMap2DPtr eng_gridmap = engine.m_gridmap_cached;
01059 gridmap_cached->setSize(
01060 eng_gridmap->getXMin(),
01061 eng_gridmap->getXMax(),
01062 eng_gridmap->getYMin(),
01063 eng_gridmap->getYMax(),
01064 eng_gridmap->getResolution());
01065
01066 }
01067
01068 template<class GRAPH_T>
01069 CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::~TNeighborAgentProps() { }
01070
01071 template<class GRAPH_T>
01072 void CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::setupComm() {
01073 using namespace mrpt::utils;
01074
01075 this->setupSubs();
01076 this->setupSrvs();
01077
01078 engine.logFmt(
01079 LVL_DEBUG,
01080 "TNeighborAgentProps: Successfully set up subscribers/services "
01081 "to agent topics for namespace [%s].",
01082 agent.topic_namespace.data.c_str());
01083
01084 has_setup_comm = true;
01085 }
01086
01087 template<class GRAPH_T>
01088 void CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::setupSrvs() {
01089
01090 cm_graph_srvclient =
01091 nh->serviceClient<mrpt_msgs::GetCMGraph>(cm_graph_service);
01092 }
01093
01094
01095 template<class GRAPH_T>
01096 void CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::setupSubs() {
01097 using namespace mrpt_msgs;
01098 using namespace mrpt::utils;
01099
01100 last_regd_nodes_sub = nh->subscribe<NodeIDWithPose_vec>(
01101 last_regd_nodes_topic,
01102 m_queue_size,
01103 &TNeighborAgentProps::fetchUpdatedNodesList, this);
01104 last_regd_id_scan_sub = nh->subscribe<NodeIDWithLaserScan>(
01105 last_regd_id_scan_topic,
01106 m_queue_size,
01107 &TNeighborAgentProps::fetchLastRegdIDScan, this);
01108 }
01109
01110 template<class GRAPH_T>
01111 void CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::
01112 fetchUpdatedNodesList(
01113 const mrpt_msgs::NodeIDWithPose_vec::ConstPtr& nodes) {
01114 MRPT_START;
01115 using namespace mrpt_msgs;
01116 using namespace mrpt_bridge;
01117 using namespace std;
01118 using namespace mrpt::utils;
01119
01120 typedef typename GRAPH_T::constraint_t::type_value pose_t;
01121 engine.logFmt(LVL_DEBUG, "In fetchUpdatedNodesList method.");
01122
01123 for (NodeIDWithPose_vec::_vec_type::const_iterator
01124 n_it = nodes->vec.begin();
01125 n_it != nodes->vec.end();
01126 ++n_it) {
01127
01128
01129 TNodeID nodeID = static_cast<TNodeID>(n_it->nodeID);
01130 std::pair<set<TNodeID>::iterator, bool> res =
01131 nodeIDs_set.insert(nodeID);
01132
01133 if (res.second) {
01134 engine.logFmt(LVL_INFO, "Just fetched a new nodeID: %lu",
01135 static_cast<unsigned long>(nodeID));
01136 nodeID_to_is_integrated.insert(make_pair(n_it->nodeID, false));
01137 }
01138
01139
01140 pose_t curr_pose;
01141
01142
01143 poses[static_cast<TNodeID>(n_it->nodeID)] =
01144 convert(n_it->pose, curr_pose);
01145 }
01146 has_new_nodes = true;
01147
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174 MRPT_END;
01175 }
01176
01177 template<class GRAPH_T>
01178 void CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::
01179 fetchLastRegdIDScan(
01180 const mrpt_msgs::NodeIDWithLaserScan::ConstPtr& last_regd_id_scan) {
01181 MRPT_START;
01182 using namespace std;
01183 using namespace mrpt::utils;
01184 ASSERT_(last_regd_id_scan);
01185 engine.logFmt(LVL_DEBUG, "In fetchLastRegdIDScan method.");
01186
01187
01188
01189 TNodeID curr_node = static_cast<TNodeID>(last_regd_id_scan->nodeID);
01190
01191
01192
01193
01194 ros_scans.push_back(*last_regd_id_scan);
01195 has_new_scans = true;
01196
01197 MRPT_END;
01198 }
01199
01200 template<class GRAPH_T>
01201 void CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::getCachedNodes(
01202 vector_uint* nodeIDs,
01203 std::map<
01204 mrpt::utils::TNodeID,
01205 node_props_t>* nodes_params,
01206 bool only_unused) const {
01207 MRPT_START;
01208 using namespace mrpt::obs;
01209 using namespace mrpt::utils;
01210 using namespace mrpt::math;
01211 using namespace std;
01212 using namespace mrpt::poses;
01213
01214
01215 ASSERT_(nodeIDs || nodes_params);
01216
01217
01218 for (std::set<TNodeID>::const_iterator
01219 n_it = nodeIDs_set.begin();
01220 n_it != nodeIDs_set.end();
01221 ++n_it) {
01222
01223
01224
01225 if (only_unused && nodeID_to_is_integrated.at(*n_it)) { continue; }
01226
01227
01228 if (nodes_params) {
01229 std::pair<TNodeID, node_props_t> params;
01230 const pose_t* p = &poses.at(*n_it);
01231
01232 params.first = *n_it;
01233 params.second.pose = *p;
01234 CObservation2DRangeScanPtr mrpt_scan = CObservation2DRangeScan::Create();
01235 const sensor_msgs::LaserScan* ros_laser_scan =
01236 this->getLaserScanByNodeID(*n_it);
01237
01238
01239
01240
01241
01242
01243 if (!ros_laser_scan) { continue; }
01244
01245 mrpt_bridge::convert(*ros_laser_scan, CPose3D(*p), *mrpt_scan);
01246 params.second.scan = mrpt_scan;
01247
01248
01249 nodes_params->insert(params);
01250
01251
01252
01253
01254
01255
01256 }
01257
01258
01259 if (nodeIDs) {
01260
01261
01262 if (!nodes_params && !this->getLaserScanByNodeID(*n_it)) {
01263 continue;
01264 }
01265
01266 nodeIDs->push_back(*n_it);
01267 }
01268 }
01269
01270 MRPT_END;
01271 }
01272
01273 template<class GRAPH_T>
01274 void CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::resetFlags() const {
01275 has_new_nodes = false;
01276 has_new_scans = false;
01277
01278 }
01279
01280 template<class GRAPH_T>
01281 bool CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::
01282 hasNewNodesBatch(int new_batch_size) {
01283 MRPT_START;
01284
01285 auto is_not_integrated = [this](const std::pair<mrpt::utils::TNodeID, bool> pair) {
01286 return (pair.second == false && getLaserScanByNodeID(pair.first));
01287 };
01288 int not_integrated_num = count_if(
01289 nodeID_to_is_integrated.begin(),
01290 nodeID_to_is_integrated.end(),
01291 is_not_integrated);
01292
01293 return (not_integrated_num >= new_batch_size);
01294
01295 MRPT_END;
01296 }
01297
01298
01299 template<class GRAPH_T>
01300 const sensor_msgs::LaserScan*
01301 CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::
01302 getLaserScanByNodeID(
01303 const mrpt::utils::TNodeID nodeID) const {
01304 MRPT_START;
01305
01306
01307 ASSERT_(nodeIDs_set.find(nodeID) != nodeIDs_set.end());
01308
01309 for (std::vector<mrpt_msgs::NodeIDWithLaserScan>::const_iterator
01310 it = ros_scans.begin();
01311 it != ros_scans.end();
01312 ++it) {
01313 if (it->nodeID == nodeID) {
01314 return &it->scan;
01315 }
01316 }
01317
01318
01319 return 0;
01320 MRPT_END;
01321 }
01322
01323 template<class GRAPH_T>
01324 void
01325 CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::fillOptPaths(
01326 const std::set<mrpt::utils::TNodeID>& nodeIDs,
01327 paths_t* opt_paths) const {
01328 MRPT_START;
01329 using namespace std;
01330 using namespace mrpt::utils;
01331 typedef std::set<TNodeID>::const_iterator set_cit;
01332
01333
01334 ASSERTMSG_(includes(nodeIDs_set.begin(), nodeIDs_set.end(),
01335 nodeIDs.begin(), nodeIDs.end()),
01336 "nodeIDs is not a strict subset of the current neighbor's nodes");
01337 ASSERT_(opt_paths);
01338
01339 for (set_cit cit = nodeIDs.begin();
01340 cit != std::prev(nodeIDs.end());
01341 ++cit) {
01342
01343 for (set_cit cit2 = std::next(cit);
01344 cit2 != nodeIDs.end();
01345 ++cit2) {
01346
01347
01348 constraint_t c = constraint_t(poses.at(*cit2) - poses.at(*cit));
01349 c.cov_inv =
01350 mrpt::math::CMatrixFixedNumeric<double,
01351 constraint_t::state_length,
01352 constraint_t::state_length>();
01353 c.cov_inv.unit();
01354 c.cov_inv *= 500;
01355
01356 opt_paths->push_back(path_t(
01357 *cit,
01358 *cit2,
01359 c));
01360
01361 engine.logFmt(LVL_DEBUG,
01362 "Filling optimal path for nodes: %lu => %lu: %s",
01363 static_cast<unsigned long>(*cit),
01364 static_cast<unsigned long>(*cit2),
01365 opt_paths->back().curr_pose_pdf.getMeanVal().asString().c_str());
01366
01367 }
01368 }
01369 MRPT_END;
01370 }
01371
01372 template<class GRAPH_T>
01373 void CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::
01374 computeGridMap() const {
01375 MRPT_START;
01376 using namespace mrpt::poses;
01377 using namespace mrpt::utils;
01378 using namespace mrpt;
01379 using namespace mrpt::math;
01380 using namespace std;
01381
01382 gridmap_cached->clear();
01383
01384 vector_uint nodeIDs;
01385 std::map<TNodeID, node_props_t> nodes_params;
01386
01387 this->getCachedNodes(&nodeIDs, &nodes_params, false);
01388
01389
01390 for (typename map<TNodeID, node_props_t>::const_iterator
01391 it = nodes_params.begin();
01392 it != nodes_params.end();
01393 ++it) {
01394 const CPose3D curr_pose_3d;
01395 gridmap_cached->insertObservation(it->second.scan.pointer(), &curr_pose_3d);
01396 }
01397
01398 MRPT_END;
01399 }
01400
01401 template<class GRAPH_T>
01402 const mrpt::maps::COccupancyGridMap2DPtr&
01403 CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::
01404 getGridMap() const {
01405 MRPT_START;
01406 if (hasNewData()) {
01407 this->computeGridMap();
01408 }
01409
01410 return gridmap_cached;
01411 MRPT_END;
01412 }
01413
01414 template<class GRAPH_T>
01415 void CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::
01416 getGridMap(mrpt::maps::COccupancyGridMap2DPtr& map) const {
01417 MRPT_START;
01418 ASSERT_(map.present());
01419
01420 if (hasNewData()) {
01421 this->computeGridMap();
01422 }
01423
01424 map->copyMapContentFrom(*gridmap_cached);
01425 MRPT_END;
01426 }
01427
01428
01429 template<class GRAPH_T>
01430 bool CGraphSlamEngine_MR<GRAPH_T>::TNeighborAgentProps::hasNewData() const {
01431 return has_new_nodes && has_new_scans;
01432 }
01433
01434 template<class GRAPH_T>
01435 CGraphSlamEngine_MR<GRAPH_T>::TOptions::TOptions(const engine_mr_t& engine_in):
01436 nodes_integration_batch_size(4),
01437 num_last_regd_nodes(10),
01438 conservative_find_initial_tfs_to_neighbors(false),
01439 inter_group_node_count_thresh_minadv(25),
01440 inter_group_node_count_thresh(40),
01441 engine(engine_in)
01442 {
01443 }
01444
01445 template<class GRAPH_T>
01446 CGraphSlamEngine_MR<GRAPH_T>::TOptions::~TOptions() {
01447 }
01448
01449 template<class GRAPH_T>
01450 void CGraphSlamEngine_MR<GRAPH_T>::TOptions::loadFromConfigFile(
01451 const mrpt::utils::CConfigFileBase& source,
01452 const std::string& section) {
01453
01454 MRPT_LOAD_CONFIG_VAR(nodes_integration_batch_size, int, source, section);
01455 MRPT_LOAD_CONFIG_VAR(num_last_regd_nodes, int, source, section);
01456
01457 MRPT_LOAD_CONFIG_VAR(conservative_find_initial_tfs_to_neighbors, bool, source, section);
01458 ASSERTMSG_(!conservative_find_initial_tfs_to_neighbors,
01459 "Conservative behavior is not yet implemented.");
01460
01461
01462 MRPT_LOAD_CONFIG_VAR(inter_group_node_count_thresh, int, source, section);
01463
01464 if (inter_group_node_count_thresh < inter_group_node_count_thresh_minadv) {
01465 engine.logFmt(mrpt::utils::LVL_ERROR,
01466 "inter_group_node_count_thresh [%d]"
01467 "is set lower than the advised minimum [%d]",
01468 inter_group_node_count_thresh,
01469 inter_group_node_count_thresh_minadv);
01470
01471 mrpt::system::sleep(2000);
01472 }
01473
01474
01475 }
01476
01477 template<class GRAPH_T>
01478 void CGraphSlamEngine_MR<GRAPH_T>::TOptions::dumpToTextStream(
01479 mrpt::utils::CStream& out) const {
01480
01481 LOADABLEOPTS_DUMP_VAR(nodes_integration_batch_size, int);
01482 LOADABLEOPTS_DUMP_VAR(num_last_regd_nodes, int);
01483 LOADABLEOPTS_DUMP_VAR(conservative_find_initial_tfs_to_neighbors, bool);
01484 LOADABLEOPTS_DUMP_VAR(inter_group_node_count_thresh, int)
01485 LOADABLEOPTS_DUMP_VAR(inter_group_node_count_thresh_minadv, int)
01486
01487 }
01488
01489
01490
01491 } }
01492
01493 #endif