tiny_slam.cpp
Go to the documentation of this file.
00001 
00010 #include <iostream>
00011 #include <ros/ros.h>
00012 #include <sensor_msgs/LaserScan.h>
00013 #include <memory>
00014 
00015 #include <nav_msgs/OccupancyGrid.h>
00016 
00017 //#define RVIZ_DEBUG 1
00018 
00019 #include "../core/sensor_data.h"
00020 #include "../ros/topic_with_transform.h"
00021 #include "../ros/rviz_grid_viewer.h"
00022 #include "../ros/utils.h"
00023 #include "../core/maps/area_occupancy_estimator.h"
00024 #include "../core/maps/const_occupancy_estimator.h"
00025 #include "../core/maps/grid_cell_strategy.h"
00026 #include "tiny_fascade.h"
00027 #include "tiny_world.h"
00028 #include "tiny_grid_cells.h"
00029 
00035 class PoseScanMatcherObserver : public GridScanMatcherObserver {
00036 public:
00037 
00042   virtual void on_scan_test(const RobotState &pose,
00043                             const TransformedLaserScan &scan,
00044                             double score) override {
00045     publish_transform("sm_curr_pose", _frame_odom, pose);
00046   }
00051   virtual void on_pose_update(const RobotState &pose,
00052                               const TransformedLaserScan &scan,
00053                               double score) override {
00054     publish_transform("sm_best_pose", _frame_odom, pose);
00055   }
00056 private:
00057     void publish_transform(const std::string& frame_id, std::string frame_odom, const RobotState& p) {
00058       publish_2D_transform(frame_id, frame_odom, p.x, p.y, p.theta);
00059     }
00060 
00061   std::string _frame_odom;
00062 };
00063 
00069 std::shared_ptr<GridCellFactory> init_cell_factory(TinyWorldParams &params) {
00070   std::string cell_type;
00071   ros::param::param<std::string>("~cell_type", cell_type, "avg");
00072 
00073   if (cell_type == "base") {
00074     params.localized_scan_quality = 0.2;
00075     params.raw_scan_quality = 0.1;
00076     return std::shared_ptr<GridCellFactory>{new TinyBaseCellFactory()};
00077   } else if (cell_type == "avg") {
00078     params.localized_scan_quality = 0.9;
00079     params.raw_scan_quality = 0.6;
00080     return std::shared_ptr<GridCellFactory>{new TinyAvgCellFactory()};
00081   } else {
00082     std::cerr << "Unknown cell type: " << cell_type << std::endl;
00083     std::exit(-1);
00084   }
00085 }
00086 
00092 std::shared_ptr<CellOccupancyEstimator> init_occ_estimator() {
00093   double occ_prob, empty_prob;
00094   ros::param::param<double>("~base_occupied_prob", occ_prob, 0.95);
00095   ros::param::param<double>("~base_empty_prob", empty_prob, 0.01);
00096 
00097   using OccEstPtr = std::shared_ptr<CellOccupancyEstimator>;
00098   std::string est_type;
00099   ros::param::param<std::string>("~occupancy_estimator", est_type, "const");
00100 
00101   if (est_type == "const") {
00102     return OccEstPtr{new ConstOccupancyEstimator(occ_prob, empty_prob)};
00103   } else if (est_type == "area") {
00104     return OccEstPtr{new AreaOccupancyEstimator(occ_prob, empty_prob)};
00105   } else {
00106     std::cerr << "Unknown estimator type: " << est_type << std::endl;
00107     std::exit(-1);
00108   }
00109 }
00110 
00115 bool init_skip_exceeding_lsr() {
00116   bool param_value;
00117   ros::param::param<bool>("~skip_exceeding_lsr_vals", param_value, false);
00118   return param_value;
00119 }
00120 
00125 TinyWorldParams init_common_world_params() {
00126   double sig_XY, sig_T, width;
00127   int lim_bad, lim_totl;
00128   ros::param::param<double>("~scmtch_sigma_XY_MonteCarlo", sig_XY, 0.2);
00129   ros::param::param<double>("~scmtch_sigma_theta_MonteCarlo", sig_T, 0.1);
00130   ros::param::param<int>("~scmtch_limit_of_bad_attempts", lim_bad, 20);
00131   ros::param::param<int>("~scmtch_limit_of_total_attempts", lim_totl, 100);
00132   ros::param::param<double>("~hole_width", width,1.5);
00133 
00134   return TinyWorldParams(sig_XY, sig_T, lim_bad, lim_totl, width);
00135 }
00136 
00141 GridMapParams init_grid_map_params() {
00142   GridMapParams params;
00143   ros::param::param<double>("~map_height_in_meters", params.height, 20);
00144   ros::param::param<double>("~map_width_in_meters", params.width, 20);
00145   ros::param::param<double>("~map_meters_per_cell", params.meters_per_cell,
00146                                                                          0.1);
00147   return params;
00148 }
00149 
00154 void init_constants_for_ros(double &ros_tf_buffer_size,
00155                             double &ros_map_rate,
00156                             int &ros_filter_queue,
00157                             int &ros_subscr_queue) {
00158   ros::param::param<double>("~ros_tf_buffer_duration",ros_tf_buffer_size,5.0);
00159   ros::param::param<double>("~ros_rviz_map_publishing_rate", ros_map_rate, 5.0);
00160   ros::param::param<int>("~ros_filter_queue_size",ros_filter_queue,1000);
00161   ros::param::param<int>("~ros_subscribers_queue_size",ros_subscr_queue,1000);
00162 }
00163 
00164 void init_frame_names(std::string &frame_odom, std::string &frame_robot_pose) {
00165   ros::param::param<std::string>("~odom", frame_odom, "odom_combined");
00166   ros::param::param<std::string>("~robot_pose", frame_robot_pose, "robot_pose");
00167 }
00168 
00172 int main(int argc, char** argv) {
00173   ros::init(argc, argv, "tinySLAM");
00174 
00175   ros::NodeHandle nh;
00176   TinyWorldParams params = init_common_world_params();
00177   GridMapParams grid_map_params = init_grid_map_params();
00178   std::shared_ptr<ScanCostEstimator> cost_est{new TinyScanCostEstimator()};
00179   std::shared_ptr<GridCellStrategy> gcs{new GridCellStrategy{
00180     init_cell_factory(params), cost_est, init_occ_estimator()}};
00181   std::shared_ptr<TinySlamFascade> slam{new TinySlamFascade(gcs,
00182     params, grid_map_params, init_skip_exceeding_lsr())};
00183 
00184   double ros_map_publishing_rate, ros_tf_buffer_size;
00185   int ros_filter_queue, ros_subscr_queue;
00186   std::string frame_odom, frame_robot_pose;
00187   init_constants_for_ros(ros_tf_buffer_size, ros_map_publishing_rate,
00188                          ros_filter_queue, ros_subscr_queue);
00189   init_frame_names(frame_odom, frame_robot_pose);
00190   TopicWithTransform<sensor_msgs::LaserScan> scan_observer(nh,
00191     "laser_scan", frame_odom, ros_tf_buffer_size,
00192     ros_filter_queue, ros_subscr_queue);
00193   scan_observer.subscribe(slam);
00194 
00195   std::shared_ptr<RvizGridViewer> viewer(
00196     new RvizGridViewer(nh.advertise<nav_msgs::OccupancyGrid>("/map", 5),
00197                        ros_map_publishing_rate, frame_odom, frame_robot_pose));
00198   slam->set_viewer(viewer);
00199 
00200 #ifdef RVIZ_DEBUG
00201   std::shared_ptr<PoseScanMatcherObserver> obs(new PoseScanMatcherObserver(frame_odom));
00202   slam->add_scan_matcher_observer(obs);
00203 #endif
00204   ros::spin();
00205 }


tiny_slam
Author(s):
autogenerated on Thu Jun 6 2019 17:44:57