11 namespace mrpt {
namespace graphslam {
namespace apps {
14 template<
class GRAPH_T>
17 template<
class GRAPH_T>
21 template<
class GRAPH_T>
23 mrpt::utils::COutputLogger*
logger,
26 parent_t(logger, options_checker, false),
55 template<
class GRAPH_T>
58 template<
class GRAPH_T>
67 template<
class GRAPH_T>
73 std::string ns =
"misc/";
76 bool m_disable_MRPT_visuals;
77 m_nh->
param<
bool>(ns +
"disable_MRPT_visuals", m_disable_MRPT_visuals,
false);
84 static_cast<int>(LVL_INFO));
90 std::string ns =
"deciders_optimizers/";
97 std::string ns =
"files/";
100 std::string config_param_path = ns +
"config";
104 "Configuration file was not set. Set %s and try again.\nExiting...",
105 config_param_path.c_str()));
114 std::string ns =
"frame_IDs/";
129 "Successfully read parameters from ROS Parameter Server");
137 template<
class GRAPH_T>
140 template<
class GRAPH_T>
144 "Initializing CGraphSlamEngine_ROS instance...");
155 "Successfully initialized CGraphSlamEngine_ROS instance.");
159 template<
class GRAPH_T>
167 "Initializing CGraphSlamEngine_MR instance...");
178 "Successfully initialized CGraphSlamEngine_MR instance.");
182 template<
class GRAPH_T>
192 ss <<
"ROS Parameters: " << endl;
196 ss <<
"Deciders / Optimizers = " << endl;
198 ss <<
"Node Registration Decider = " <<
m_node_reg << endl;
199 ss <<
"Edge Registration Decider = " <<
m_edge_reg << endl;
200 ss <<
"GraphSLAM Optimizer = " <<
m_optimizer << endl;
203 ss <<
"Filenames: " << endl;
205 ss <<
"Configuration .ini file = " << this->
m_ini_fname << endl;
206 ss <<
"Ground truth filename = " << (!this->
m_gt_fname.empty()
211 ss <<
"Miscellaneous: " << endl;
213 ss <<
"Enable MRPT visuals? = " <<
216 ss <<
"Logging verbosity Level = " <<
217 COutputLogger::logging_levels_to_names
218 #if MRPT_VERSION>=0x199 227 template<
class GRAPH_T>
232 std::string ros_params(
"");
234 std::string mrpt_params(
"");
237 *str_out += ros_params;
239 *str_out += mrpt_params;
244 template<
class GRAPH_T>
251 template<
class GRAPH_T>
260 template<
class GRAPH_T>
262 this->
m_logger->logFmt(LVL_DEBUG,
"Verifying user input...");
266 bool node_success, edge_success, optimizer_success;
281 "\nNode Registration Decider \"%s\" is not available",
288 "\nEdge Registration Decider \"%s\" is not available.",
293 if (!optimizer_success) {
295 "\ngraphSLAM Optimizser \"%s\" is not available.",
307 "\n.ini configuration file \"%s\"doesn't exist. " 308 "Please specify a valid pathname.\nExiting...\n",
315 "\nGround truth file \"%s\"doesn't exist." 316 "Either unset the corresponding ROS parameter or specify a valid pathname.\n" 323 template<
class GRAPH_T>
327 "Setting up ROS-related subscribers, publishers, services...");
339 template<
class GRAPH_T>
341 this->
m_logger->logFmt(LVL_INFO,
"Setting up the subscribers...");
344 std::string ns =
"input/";
369 template<
class GRAPH_T>
371 this->
m_logger->logFmt(LVL_INFO,
"Setting up the publishers...");
374 std::string ns =
"feedback/";
421 template<
class GRAPH_T>
423 this->
m_logger->logFmt(LVL_INFO,
"Setting up the services...");
429 template<
class GRAPH_T>
440 pose_t mrpt_pose = this->
m_engine->getCurrentRobotPosEstimation();
446 geometry_msgs::TransformStamped anchor_base_link_transform;
452 anchor_base_link_transform.transform.translation.x = mrpt_pose.x();
453 anchor_base_link_transform.transform.translation.y = mrpt_pose.y();
454 anchor_base_link_transform.transform.translation.z = 0;
457 anchor_base_link_transform.transform.rotation =
474 geometry_msgs::PoseStamped geom_pose;
475 geom_pose.header.stamp = timestamp;
488 "Publishing the current robot trajectory");
489 typename GRAPH_T::global_poses_t graph_poses;
490 #if MRPT_VERSION>=0x199 491 graph_poses = this->
m_engine->getRobotEstimatedTrajectory();
493 this->
m_engine->getRobotEstimatedTrajectory(&graph_poses);
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();
512 n_cit != graph_poses.end();
515 geometry_msgs::PoseStamped geom_pose_stamped;
519 const pose_t& mrpt_pose = n_cit->second;
521 geom_poses.poses.push_back(geom_pose);
522 geom_pose_stamped.pose = geom_pose;
525 geom_pose_stamped.header.stamp = timestamp;
526 geom_pose_stamped.header.seq =
m_pub_seq;
529 path.poses.push_back(geom_pose_stamped);
547 mrpt::maps::COccupancyGridMap2D::Ptr mrpt_gridmap =
548 mrpt::maps::COccupancyGridMap2D::Create();
549 this->
m_engine->getMap(mrpt_gridmap, &mrpt_time);
564 mrpt_msgs::GraphSlamStats
stats;
567 map<string, int> node_stats;
568 map<string, int> edge_stats;
569 vector<double> def_energy_vec;
572 this->
m_engine->getGraphSlamStats(&node_stats,
577 stats.nodes_total = node_stats[
"nodes_total"];
578 stats.edges_total = edge_stats[
"edges_total"];
579 if (edge_stats.find(
"ICP2D") != edge_stats.end()) {
580 stats.edges_ICP2D = edge_stats[
"ICP2D"];
582 if (edge_stats.find(
"ICP3D") != edge_stats.end()) {
583 stats.edges_ICP3D = edge_stats[
"ICP3D"];
585 if (edge_stats.find(
"Odometry") != edge_stats.end()) {
586 stats.edges_odom = edge_stats[
"Odometry"];
588 stats.loop_closures = edge_stats[
"loop_closures"];
591 this->
m_engine->getDeformationEnergyVector(
592 &stats.slam_evaluation_metric);
614 template<
class GRAPH_T>
616 const sensor_msgs::LaserScan::ConstPtr& ros_laser_scan) {
623 "sniffLaserScan: Received a LaserScan msg. Converting it to MRPT format...");
635 template<
class GRAPH_T>
637 const nav_msgs::Odometry::ConstPtr& ros_odom) {
645 "sniffOdom: Received an odometry msg. Converting it to MRPT format...");
662 ros_odom->pose.pose.position.x;
664 ros_odom->pose.pose.position.y;
666 ros_odom->pose.pose.position.z;
670 ros_odom->pose.pose.orientation;
676 ros_odom->header.stamp,
694 geometry_msgs::PoseStamped pose_stamped;
695 pose_stamped.header = ros_odom->header;
706 ss <<
"Odometry - MRPT format:\t" <<
m_mrpt_odom->odometry << endl;
707 this->
m_logger->logFmt(LVL_DEBUG,
"%s", ss.str().c_str());
714 template<
class GRAPH_T>
719 template<
class GRAPH_T>
724 template<
class GRAPH_T>
726 mrpt::obs::CObservation::Ptr& observ) {
735 template<
class GRAPH_T>
737 mrpt::obs::CObservation::Ptr& observ) {
749 template<
class GRAPH_T>
void readROSParameters()
read configuration parameters from the ROS parameter server.
void readParams()
Read the problem configuration parameters.
optimizers_t optimizers_map
void verifyUserInput()
Verify that the parameters read are valid and can be used with the CGraphSlamEngine_ROS instance...
virtual void createDeciderOptimizerMappings()
virtual bool checkOptimizerExists(std::string given_opt) const
tf2_ros::TransformBroadcaster m_broadcaster
node_regs_t node_regs_map
pose_t m_input_odometry_offset
mrpt::graphslam::CGraphSlamEngine< GRAPH_T > * m_engine
void publish(const boost::shared_ptr< M > &message) const
bool usePublishersBroadcasters()
Provide feedback about the SLAM operation using ROS publilshers, update the registered frames using t...
CGraphSlamHandler_ROS(mrpt::utils::COutputLogger *logger, TUserOptionsChecker< GRAPH_T > *options_checker, ros::NodeHandle *nh_in)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void initEngine_ROS()
Initialize the CGraphslamEngine_* object.
#define THROW_EXCEPTION(msg)
std::string getParamsAsString()
bool m_first_time_in_sniff_odom
Initial offset of the received odometry.
bool BASE_IMPEXP fileExists(const std::string &fileName)
ros::Subscriber m_laser_scan_sub
static const std::string sep_subheader
std::string m_curr_robot_pos_topic
size_t m_measurement_cnt
Total counter of the processed measurements.
mrpt::obs::CObservation2DRangeScan::Ptr m_mrpt_laser_scan
GRAPH_T::constraint_t::type_value pose_t
type of underlying poses (2D/3D).
mrpt::utils::COutputLogger * m_logger
virtual void dumpOptimizersToConsole() const
edge_regs_t edge_regs_map
ros::Subscriber m_odom_sub
bool m_received_laser_scan
VerbosityLevel m_min_logging_level
Minimum logging level for the current class instance.
ros::Publisher m_robot_tr_poses_pub
static const std::string sep_header
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
std::string m_base_link_frame_id
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
geometry_msgs::TransformStamped m_anchor_odom_transform
ros::NodeHandle * m_nh
Pointer to the Ros NodeHanle instance.
mrpt::graphslam::apps::TUserOptionsChecker< GRAPH_T > * m_options_checker
void sniffOdom(const nav_msgs::Odometry::ConstPtr &ros_odom)
Callback method for handling incoming odometry measurements in a ROS topic.
std::string m_odom_frame_id
virtual void dumpRegistrarsToConsole(std::string reg_type="all") const
void _process(mrpt::obs::CObservation::Ptr &observ)
Low level wrapper for executing the CGraphSlamEngine_ROS::execGraphSlamStep method.
void sniffLaserScan(const sensor_msgs::LaserScan::ConstPtr &ros_laser_scan)
Callback method for handling incoming LaserScans objects in a ROS topic.
ros::Publisher m_odom_trajectory_pub
void setupComm()
Wrapper method around the protected setup* class methods.
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void getROSParameters(std::string *str_out)
Fill in the given string with the parameters that have been read from the ROS parameter server...
size_t m_graph_nodes_last_size
std::string m_odom_trajectory_topic
ros::Publisher m_gridmap_pub
void convert(const ros::Time &src, mrpt::system::TTimeStamp &des)
nav_msgs::Path m_odom_path
Odometry path of the robot. Handy mostly for visualization reasons.
std::string getParamsAsString() const
std::string m_gridmap_topic
std::string m_anchor_frame_id
Frame that the robot starts from. In a single-robot SLAM setup this can be set to the world frame...
std::string m_laser_scan_topic
void printParams()
Print in a compact manner the overall problem configuration parameters.
int m_pub_seq
Times a messge has been published => usePublishersBroadcasters method is called.
ros::Publisher m_curr_robot_pos_pub
static geometry_msgs::Quaternion createQuaternionMsgFromYaw(double yaw)
bool queryObserverForEvents()
mrpt::graphslam::CWindowManager * m_win_manager
bool getParam(const std::string &key, std::string &s) const
static CAST_TO::Ptr from(const CAST_FROM_PTR &ptr)
void resetReceivedFlags()
Reset the flags indicating whether we have received new data (odometry, laser scans etc...
virtual void populateDeciderOptimizerProperties()
ros::Publisher m_stats_pub
mrpt::obs::CObservationOdometry::Ptr m_mrpt_odom
Received laser scan - converted into MRPT CObservation* format.
void processObservation(mrpt::obs::CObservation::Ptr &observ)
Process an incoming measurement.
std::string m_robot_trajectory_topic
int m_queue_size
ROS topic publisher standard queue size.
mrpt::graphslam::CGraphSlamEngine derived class for executing multi-robot graphSLAM ...
ros::Publisher m_robot_trajectory_pub
void readConfigFname(const std::string &fname)
#define ASSERTMSG_(f, __ERROR_MSG)
std::string m_robot_tr_poses_topic
virtual bool checkRegistrationDeciderExists(std::string given_reg, std::string reg_type) const
std::string m_stats_topic
bool m_received_point_cloud