12 #include <mrpt/ros1bridge/time.h>
13 #include <mrpt/ros1bridge/laser_scan.h>
14 #include <mrpt/ros1bridge/pose.h>
15 #include <mrpt/ros1bridge/map.h>
33 template <
class GRAPH_T>
36 template <
class GRAPH_T>
40 template <
class GRAPH_T>
42 mrpt::system::COutputLogger*
logger,
46 using namespace mrpt::obs;
72 template <
class GRAPH_T>
77 template <
class GRAPH_T>
82 ASSERT_(!this->m_ini_fname.empty());
83 parent_t::readConfigFname(this->m_ini_fname);
86 template <
class GRAPH_T>
91 std::string ns =
"misc/";
94 bool m_disable_MRPT_visuals;
96 ns +
"disable_MRPT_visuals", m_disable_MRPT_visuals,
false);
97 this->m_enable_visuals = !m_disable_MRPT_visuals;
101 m_nh->
param<
int>(ns +
"verbosity", lvl,
static_cast<int>(LVL_INFO));
107 std::string ns =
"deciders_optimizers/";
114 std::string ns =
"files/";
117 std::string config_param_path = ns +
"config";
118 bool found_config =
m_nh->
getParam(ns +
"config", this->m_ini_fname);
120 found_config, mrpt::format(
121 "Configuration file was not set. Set %s and try "
122 "again.\nExiting...",
123 config_param_path.c_str()));
132 std::string ns =
"frame_IDs/";
143 this->m_options_checker->createDeciderOptimizerMappings();
144 this->m_options_checker->populateDeciderOptimizerProperties();
147 this->m_logger->logFmt(
148 LVL_DEBUG,
"Successfully read parameters from ROS Parameter Server");
151 if (this->m_enable_visuals)
153 this->initVisualization();
157 template <
class GRAPH_T>
162 template <
class GRAPH_T>
165 this->m_logger->logFmt(
166 LVL_WARN,
"Initializing CGraphSlamEngine_ROS instance...");
168 m_nh, this->m_ini_fname,
169 "", this->m_gt_fname, this->m_win_manager,
170 this->m_options_checker->node_regs_map[
m_node_reg](),
171 this->m_options_checker->edge_regs_map[
m_edge_reg](),
172 this->m_options_checker->optimizers_map[
m_optimizer]());
173 this->m_logger->logFmt(
174 LVL_WARN,
"Successfully initialized CGraphSlamEngine_ROS instance.");
177 template <
class GRAPH_T>
180 this->m_options_checker->node_regs_map[
m_node_reg]();
181 this->m_options_checker->edge_regs_map[
m_edge_reg]();
182 this->m_options_checker->optimizers_map[
m_optimizer]();
184 this->m_logger->logFmt(
185 LVL_WARN,
"Initializing CGraphSlamEngine_MR instance...");
187 m_nh, this->m_ini_fname,
188 "", this->m_gt_fname, this->m_win_manager,
189 this->m_options_checker->node_regs_map[
m_node_reg](),
190 this->m_options_checker->edge_regs_map[
m_edge_reg](),
191 this->m_options_checker->optimizers_map[
m_optimizer]());
192 this->m_logger->logFmt(
193 LVL_WARN,
"Successfully initialized CGraphSlamEngine_MR instance.");
196 template <
class GRAPH_T>
205 ss <<
"ROS Parameters: " << endl;
209 ss <<
"Deciders / Optimizers = " << endl;
211 ss <<
"Node Registration Decider = " <<
m_node_reg << endl;
212 ss <<
"Edge Registration Decider = " <<
m_edge_reg << endl;
213 ss <<
"GraphSLAM Optimizer = " <<
m_optimizer << endl;
216 ss <<
"Filenames: " << endl;
218 ss <<
"Configuration .ini file = " << this->m_ini_fname << endl;
219 ss <<
"Ground truth filename = "
220 << (!this->m_gt_fname.empty() ? this->m_gt_fname :
"NONE") << endl;
223 ss <<
"Miscellaneous: " << endl;
225 ss <<
"Enable MRPT visuals? = "
226 << (this->m_enable_visuals ?
"TRUE" :
"FALSE") << endl;
227 ss <<
"Logging verbosity Level = "
235 template <
class GRAPH_T>
241 std::string ros_params(
"");
243 std::string mrpt_params(
"");
244 parent_t::getParamsAsString(&mrpt_params);
246 *str_out += ros_params;
248 *str_out += mrpt_params;
253 template <
class GRAPH_T>
261 template <
class GRAPH_T>
265 parent_t::printParams();
269 template <
class GRAPH_T>
272 this->m_logger->logFmt(LVL_DEBUG,
"Verifying user input...");
275 bool node_success, edge_success, optimizer_success;
278 node_success = this->m_options_checker->checkRegistrationDeciderExists(
280 edge_success = this->m_options_checker->checkRegistrationDeciderExists(
283 this->m_options_checker->checkOptimizerExists(
m_optimizer);
287 this->m_logger->logFmt(
288 LVL_ERROR,
"\nNode Registration Decider \"%s\" is not available",
290 this->m_options_checker->dumpRegistrarsToConsole(
"node");
295 this->m_logger->logFmt(
296 LVL_ERROR,
"\nEdge Registration Decider \"%s\" is not available.",
298 this->m_options_checker->dumpRegistrarsToConsole(
"edge");
301 if (!optimizer_success)
303 this->m_logger->logFmt(
304 LVL_ERROR,
"\ngraphSLAM Optimizser \"%s\" is not available.",
306 this->m_options_checker->dumpOptimizersToConsole();
313 bool ini_exists = system::fileExists(this->m_ini_fname);
316 "\n.ini configuration file \"%s\"doesn't exist. "
317 "Please specify a valid pathname.\nExiting...\n",
318 this->m_ini_fname.c_str()));
320 if (!this->m_gt_fname.empty())
322 bool gt_exists = system::fileExists(this->m_gt_fname);
325 "\nGround truth file \"%s\"doesn't exist."
326 "Either unset the corresponding ROS parameter or "
327 "specify a valid pathname.\n"
329 this->m_gt_fname.c_str()));
334 template <
class GRAPH_T>
337 this->m_logger->logFmt(
339 "Setting up ROS-related subscribers, publishers, services...");
351 template <
class GRAPH_T>
354 this->m_logger->logFmt(LVL_INFO,
"Setting up the subscribers...");
357 std::string ns =
"input/";
378 template <
class GRAPH_T>
381 this->m_logger->logFmt(LVL_INFO,
"Setting up the publishers...");
384 std::string ns =
"feedback/";
422 template <
class GRAPH_T>
425 this->m_logger->logFmt(LVL_INFO,
"Setting up the services...");
431 template <
class GRAPH_T>
442 pose_t mrpt_pose = this->m_engine->getCurrentRobotPosEstimation();
448 geometry_msgs::TransformStamped anchor_base_link_transform;
454 anchor_base_link_transform.transform.translation.x = mrpt_pose.x();
455 anchor_base_link_transform.transform.translation.y = mrpt_pose.y();
456 anchor_base_link_transform.transform.translation.z = 0;
459 anchor_base_link_transform.transform.rotation =
477 geometry_msgs::PoseStamped geom_pose;
478 geom_pose.header.stamp = timestamp;
480 geom_pose.header.frame_id =
484 geom_pose.pose = mrpt::ros1bridge::toROS_Pose(mrpt_pose);
491 this->m_logger->logFmt(
492 LVL_DEBUG,
"Publishing the current robot trajectory");
493 typename GRAPH_T::global_poses_t graph_poses;
494 graph_poses = this->m_engine->getRobotEstimatedTrajectory();
499 path.header.stamp = timestamp;
507 geometry_msgs::PoseArray geom_poses;
508 geom_poses.header.stamp = timestamp;
511 for (
auto n_cit = graph_poses.begin(); n_cit != graph_poses.end();
514 geometry_msgs::PoseStamped geom_pose_stamped;
515 geometry_msgs::Pose geom_pose;
518 const pose_t& mrpt_pose = n_cit->second;
519 geom_pose = mrpt::ros1bridge::toROS_Pose(mrpt_pose);
520 geom_poses.poses.push_back(geom_pose);
521 geom_pose_stamped.pose = geom_pose;
524 geom_pose_stamped.header.stamp = timestamp;
525 geom_pose_stamped.header.seq =
m_pub_seq;
528 path.poses.push_back(geom_pose_stamped);
547 mrpt::system::TTimeStamp mrpt_time;
548 auto mrpt_gridmap = mrpt::maps::COccupancyGridMap2D::Create();
549 this->m_engine->getMap(mrpt_gridmap, &mrpt_time);
552 h.stamp = mrpt::ros1bridge::toROS(mrpt_time);
557 nav_msgs::OccupancyGrid nav_gridmap;
558 mrpt::ros1bridge::toROS(*mrpt_gridmap, nav_gridmap, h);
564 mrpt_msgs::GraphSlamStats stats;
567 map<string, int> node_stats;
568 map<string, int> edge_stats;
569 vector<double> def_energy_vec;
570 mrpt::system::TTimeStamp mrpt_time;
572 this->m_engine->getGraphSlamStats(&node_stats, &edge_stats, &mrpt_time);
575 stats.nodes_total = node_stats[
"nodes_total"];
576 stats.edges_total = edge_stats[
"edges_total"];
577 if (edge_stats.find(
"ICP2D") != edge_stats.end())
579 stats.edges_icp_2d = edge_stats[
"ICP2D"];
581 if (edge_stats.find(
"ICP3D") != edge_stats.end())
583 stats.edges_icp_3d = edge_stats[
"ICP3D"];
585 if (edge_stats.find(
"Odometry") != edge_stats.end())
587 stats.edges_odom = edge_stats[
"Odometry"];
589 stats.loop_closures = edge_stats[
"loop_closures"];
592 this->m_engine->getDeformationEnergyVector(
593 &stats.slam_evaluation_metric);
595 stats.header.stamp = mrpt::ros1bridge::toROS(mrpt_time);
604 if (this->m_enable_visuals)
606 ret_val = this->queryObserverForEvents();
613 template <
class GRAPH_T>
615 const sensor_msgs::LaserScan::ConstPtr& ros_laser_scan)
618 using namespace mrpt::obs;
620 this->m_logger->logFmt(
622 "sniffLaserScan: Received a LaserScan msg. Converting it to MRPT "
627 mrpt::poses::CPose3D rel_pose;
631 CObservation::Ptr tmp =
636 template <
class GRAPH_T>
638 const nav_msgs::Odometry::ConstPtr& ros_odom)
641 using namespace mrpt::obs;
642 using namespace mrpt::poses;
644 this->m_logger->logFmt(
646 "sniffOdom: Received an odometry msg. Converting it to MRPT format...");
663 ros_odom->pose.pose.position.x;
665 ros_odom->pose.pose.position.y;
667 ros_odom->pose.pose.position.z;
671 ros_odom->pose.pose.orientation;
676 m_mrpt_odom->timestamp = mrpt::ros1bridge::fromROS(ros_odom->header.stamp);
678 mrpt::poses::CPose2D(mrpt::ros1bridge::fromROS(ros_odom->pose.pose));
692 geometry_msgs::PoseStamped pose_stamped;
693 pose_stamped.header = ros_odom->header;
696 pose_stamped.pose = mrpt::ros1bridge::toROS_Pose(
m_mrpt_odom->odometry);
702 ss <<
"Odometry - MRPT format:\t" <<
m_mrpt_odom->odometry << endl;
703 this->m_logger->logFmt(LVL_DEBUG,
"%s", ss.str().c_str());
706 CObservation::Ptr tmp =
707 mrpt::ptr_cast<mrpt::obs::CObservation>::from(
m_mrpt_odom);
711 template <
class GRAPH_T>
714 THROW_EXCEPTION(
"Method is not implemented yet.");
716 template <
class GRAPH_T>
719 THROW_EXCEPTION(
"Method is not implemented yet.");
721 template <
class GRAPH_T>
723 mrpt::obs::CObservation::Ptr& observ)
731 template <
class GRAPH_T>
733 mrpt::obs::CObservation::Ptr& observ)
738 if (!this->m_engine->isPaused())
745 template <
class GRAPH_T>