parameter_server.cpp
Go to the documentation of this file.
00001 /* This file is part of RGBDSLAM.
00002  * 
00003  * RGBDSLAM is free software: you can redistribute it and/or modify
00004  * it under the terms of the GNU General Public License as published by
00005  * the Free Software Foundation, either version 3 of the License, or
00006  * (at your option) any later version.
00007  * 
00008  * RGBDSLAM is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  * GNU General Public License for more details.
00012  * 
00013  * You should have received a copy of the GNU General Public License
00014  * along with RGBDSLAM.  If not, see <http://www.gnu.org/licenses/>.
00015  */
00016 #include "parameter_server.h"
00017 
00018 //using namespace std;
00019 
00020 ParameterServer* ParameterServer::_instance = NULL;
00021 
00022 void ParameterServer::defaultConfig() {
00023   double dInf = std::numeric_limits<double>::infinity();
00024   // Input data settings
00025   addOption("topic_image_mono",              std::string("/camera/rgb/image_color"),    "Color or grayscale image ros topic");
00026   addOption("camera_info_topic",             std::string("/camera/rgb/camera_info"),    "Required for backprojection if no pointcloud topic is given");
00027   addOption("topic_image_depth",             std::string("/camera/depth_registered/sw_registered/image_rect_raw"),        "Depth image ros topic");
00028   addOption("topic_points",                  std::string(""),                           "If omitted, xyz will be computed from depth image. ");
00029   addOption("wide_topic",                    std::string(""),                           "Topics for stereo cam, e.g. /wide_stereo/left/image_mono");
00030   addOption("wide_cloud_topic",              std::string(""),                           "Topics for stereo cam e.g. /wide_stereo/points2");
00031   addOption("bagfile_name",                  std::string(""),                           "Read data from a bagfile, make sure to enter the right topics above");
00032   addOption("subscriber_queue_size",         static_cast<int> (3),                      "Cache incoming data (carefully, RGB-D Clouds are 10MB each)");
00033   addOption("drop_async_frames",             static_cast<bool> (false),                 "Check timestamps of depth and visual image, reject if not in sync ");
00034   addOption("depth_scaling_factor",          static_cast<double> (1.0),                 "Some kinects have a wrongly scaled depth");
00035   addOption("data_skip_step",                static_cast<int> (1),                      "Skip every n-th frame completely  ");
00036   addOption("cloud_creation_skip_step",      static_cast<int> (2),                      "Downsampling factor (rows and colums, so size reduction is quadratic) for the point cloud. Only active if cloud is computed (i.e. \"topic_points\" is empty. This value multiplies to emm__skip_step and visualization_skip_step.");
00037   addOption("create_cloud_every_nth_node",   static_cast<int> (1),                      "Create a point cloud only for every nth frame");
00038   addOption("maximum_depth",                 static_cast<double> (dInf),                "Clip far points when reconstructing the cloud. In meter.");
00039   addOption("minimum_depth",                 static_cast<double> (0.1),                 "Clip near points when reconstructing the cloud. In meter.");
00040   addOption("encoding_bgr",                  static_cast<bool> (true),                   "Whether the color image encoding is bgr (fuerte openni_launch) as opposed to rgb (electric openni_camera)");
00041   //Camera settings (Internal calibration is not consistent though. It's best, the input is calibrated.)
00042   addOption("depth_camera_fx",               static_cast<double> (0.0),                 "Focal length w.r.t. horizontal pixel size. Use zero to use values from CameraInfo");
00043   addOption("depth_camera_fy",               static_cast<double> (0.0),                 "Focal length w.r.t. vertical pixel size. Use zero to use values from CameraInfo");
00044   addOption("depth_camera_cx",               static_cast<double> (0.0),                 "Horizontal image center. Use zero to use values from CameraInfo");
00045   addOption("depth_camera_cy",               static_cast<double> (0.0),                 "Vertical image center. Use zero to use values from CameraInfo");
00046   addOption("sigma_depth",                   static_cast<double> (0.01),                "Factor c for the standard deviation of depth measurements: sigma_Z = c * depth * depth. Khoshelham 2012 (0.001425) seems to be a bit overconfident.");
00047 
00048   // Output data settings
00049   addOption("store_pointclouds",             static_cast<bool> (true),                  "If the point clouds are not needed online, setting this to false saves lots of memory ");
00050   addOption("individual_cloud_out_topic",    std::string("/rgbdslam/batch_clouds"),     "Use this topic when sending the individual clouds with the computed transforms, e.g. for octomap_server");
00051   addOption("aggregate_cloud_out_topic",     std::string("/rgbdslam/aggregate_clouds"), "Use this topic when sending the all points in one big registered cloud");
00052   addOption("online_cloud_out_topic",        std::string("/rgbdslam/online_clouds"),    "Use this topic to get the latest cloud.");
00053   addOption("send_clouds_rate",              static_cast<double> (5),                   "When sending the point clouds (e.g. to RVIZ or Octomap Server) limit sending to this many clouds per second");
00054   addOption("publisher_queue_size",          static_cast<int> (5),                      "ROS standard parameter for all publishers");
00055   // Octomap data settings
00056   addOption("octomap_resolution",            static_cast<double> (0.05),                "Minimal voxel size of the OctoMap, when saved directly (not when used in conjunction with octomap_server)");
00057   addOption("octomap_autosave_step",         static_cast<int> (50),                     "Automatically save the octomap repeatedly after insertion of this many clouds");
00058   addOption("octomap_clear_after_save",      static_cast<bool> (false),                  "Clear out octomap after (final) saving.");
00059   addOption("octomap_clear_raycasted_clouds",static_cast<bool> (false),                  "Clear out point clouds after raycasting.");
00060   addOption("octomap_occupancy_threshold",   static_cast<double> (0.5),                 "Occupancy threshold for binary OctoMap");
00061   addOption("octomap_clamping_max",          static_cast<double> (0.999),               "Maximum value for clamping of occupancy threshold in voxels");
00062   addOption("octomap_clamping_min",          static_cast<double> (0.001),                 "Minimum value for clamping of occupancy threshold in voxels");
00063   addOption("octomap_prob_hit",              static_cast<double> (0.9),                 "Octomap sensor model: Probability value for hit.");
00064   addOption("octomap_prob_miss",             static_cast<double> (0.4),                 "Octomap sensor model: Probability value for miss.");
00065   addOption("octomap_online_creation",       static_cast<bool> (false),                 "Create the octomap during mapping. If using this, every node will be rendered to the octomap directly after they have been added to the graph (and graph optimization, if not skipped b/c of optimizer_skip_step).");
00066   addOption("screencast_path_prefix",        std::string(""),                           "If set: capture frames for a screencast with this path as filename-prefix.");
00067   addOption("transform_individual_clouds",   static_cast<bool> (false),                 "If set: Transform individually saved pcds into common coordinate frame.");
00068   addOption("compress_output_bagfile",       static_cast<bool> (true),                  "Whether to enable bz2 compression when saving bagfiles");
00069   addOption("occupancy_filter_threshold",    static_cast<double> (0.9),                 "Remove points located at voxels with occupancy probability below this.");
00070 
00071   // TF information settings 
00072   addOption("fixed_frame_name",              std::string("/map"),                       "The computed camera transforms are with respect to this frame. It is set to the identity for the first frame processed or, if ground truth is available, to the ground truth of the first frame");
00073   addOption("odom_frame_name",               std::string(""),                           "A fixed frame estimation from somewhere else (e.g. odometry, laser-based mapping). Doesn't need to correspond to the pose of the fixed_frame_name");
00074   addOption("odom_target_frame_name",        std::string(""),                           "If given, try to get the odometry transformation from odom_frame_name to this frame instead of the frame of the points. Meant to compute the offset between robot base and sensor online.");
00075   addOption("ground_truth_frame_name",       std::string(""),                           "Use empty string if no ground truth tf frame available");
00076   addOption("base_frame_name",               std::string("/openni_rgb_optical_frame"),               "If the camera is articulated use robot base");
00077   addOption("fixed_camera",                  static_cast<bool> (true),                  "Is camera fixed relative to base?");
00078 
00079   // Visual Features, to activate GPU-based features see CMakeLists.txt 
00080   addOption("feature_detector_type",         std::string("ORB"),                        "SIFTGPU, SURF, SIFT or ORB, or variants like GridDynamicORB or DynamicSURF (however, not GridXXX only, and not in combination with SIFTGPU)");
00081   addOption("feature_extractor_type",        std::string("ORB"),                        "SIFTGPU, SURF, SIFT or ORB");
00082   addOption("matcher_type",                  std::string("FLANN"),                      "SIFTGPU (matching on the gpu) or FLANN or BRUTEFORCE. FLANN is fast for SURF. For ORB FLANN is slower than Bruteforce for few keypoints (less than ~3000).");
00083   addOption("max_keypoints",                 static_cast<int> (600),                    "Extract no more than this many keypoints ");
00084   addOption("min_keypoints",                 static_cast<int> (000),                    "Deprecated: Extract no less than this many keypoints ");
00085   addOption("min_matches",                   static_cast<int> (20),                     "Don't try RANSAC if less than this many matches (if using SiftGPU and GLSL you should use max. 60 matches)");
00086   addOption("max_matches",                   static_cast<int> (300),                    "Reduce the feature matches to the best n, speeding up ransac (but not feature matching itself)");
00087   addOption("detector_grid_resolution",      static_cast<int> (3),                      "If >1, split image into x by x subimages (overlapping b/c of keypoint size) and detect keypoints in parallel. Good to spread ORB keypoints over the image and speed up the slow SURF detection.");
00088   addOption("sufficient_matches",            static_cast<int> (1e9),                    "Extract no less than this many only honored by the adjustable SURF and FAST features");
00089   addOption("adjuster_max_iterations",       static_cast<int> (5),                      "If outside of bounds for max_kp and min_kp, retry this many times with adapted threshold");
00090   addOption("use_feature_min_depth",         static_cast<bool>(false),                  "Consider the nearest point in the neighborhood of the feature as its depth, as it will dominate the motion");
00091   addOption("use_feature_mask",              static_cast<bool>(false),                  "Whether to extract features without depth");
00092   addOption("use_root_sift",                 static_cast<bool>(true),                   "Whether to use euclidean distance or Hellman kernel for feature comparison");
00093   addOption("siftgpu_with_cuda",             static_cast<bool>(false),                  "Use CUDA instead of GLSL for the computation of SIFTGPU features. Requires CUDA drivers to be installed.");
00094 
00095   // Frontend settings 
00096   addOption("max_translation_meter",         static_cast<double> (1e10),                "Sanity check for smooth motion.");
00097   addOption("max_rotation_degree",           static_cast<double> (360),                    "Sanity check for smooth motion.");
00098   addOption("min_translation_meter",         static_cast<double> (0.0),                 "Frames with motion less than this, will be omitted ");
00099   addOption("min_rotation_degree",           static_cast<double> (0.0),                 "Frames with motion less than this, will be omitted ");
00100   addOption("max_dist_for_inliers",          static_cast<double> (3),                   "Mahalanobis distance for matches to be considered inliers by ransac");
00101   addOption("ransac_iterations",             static_cast<int> (200),                    "Number of iterations for registration");
00102   addOption("ransac_termination_inlier_pct", static_cast<double> (60.0),                "Percentage of matches that need to be inliers to succesfully terminate ransac before the 'ransac_iterations' have been reached");
00103   addOption("g2o_transformation_refinement", static_cast<int> (0),                      "Use g2o to refine the ransac result for that many iterations, i.e. optimize the Mahalanobis distance in a final step. Use zero to disable.");
00104   addOption("max_connections",               static_cast<int> (-1),                     "Stop frame comparisons after this many succesfully found spation relations. Negative value: No limit.");
00105   addOption("geodesic_depth",                static_cast<int> (3),                      "For comparisons with neighbors, consider those with a graph distance (hop count) equal or below this value as neighbors of the direct predecessor");
00106   addOption("predecessor_candidates",        static_cast<int> (4),                      "Compare Features to this many direct sequential predecessors");
00107   addOption("neighbor_candidates",           static_cast<int> (4),                      "Compare Features to this many graph neighbours. Sample from the candidates");
00108   addOption("min_sampled_candidates",        static_cast<int> (4),                      "Compare Features to this many uniformly sampled nodes for corrspondences ");
00109   addOption("use_icp",                       static_cast<bool> (false),                 "Activate ICP Fallback. Ignored if ICP is not compiled in (see top of CMakeLists.txt) ");
00110   addOption("icp_method",                    std::string("icp"),                        "gicp, icp or icp_nl");
00111   addOption("gicp_max_cloud_size",           static_cast<int> (10000),                  "Subsample for increased speed");
00112   addOption("emm__skip_step",                static_cast<int> (8),                      "When evaluating the transformation, subsample rows and cols with this stepping");
00113   addOption("emm__mark_outliers",            static_cast<bool> (false),                 "Mark outliers in the observation likelihood evaluation with colors. Red: point would have blocked the view of an earlier observation. Cyan: An earlier observation should have blocked the view to this point");
00114   addOption("observability_threshold",       static_cast<double> (-0.6),                "What fraction of the aligned points are required to be in observable position (i.e. don't contradict the sensor physics)");
00115   addOption("allow_features_without_depth",  static_cast<bool> (false),                 "Keep matches without depth (currently has no benefit)");
00116 
00117   //Backend
00118   addOption("pose_relative_to",              std::string("first"),                      "This option allows to choose which frame(s) should be set fixed during optimization: first, previous, inaffected, largest_loop. The latter sets all frames as fixed to which no transformation has been found.");
00119   addOption("optimizer_iterations",          static_cast<double> (0.01),                "Maximum of iterations. If between 0 and 1, optimizer stops after improvement is less than the given fraction (default: 1%).");
00120   addOption("optimizer_skip_step",           static_cast<int> (1),                      "Optimize every n-th frame. Set negative for offline operation ");
00121   addOption("optimize_landmarks",            static_cast<bool> (false),                 "Consider the features as landmarks in optimization. Otherwise optimize camera pose graph only");
00122   addOption("concurrent_optimization",       static_cast<bool> (true),                  "Do graph optimization in a seperate thread");
00123   addOption("backend_solver",                std::string("pcg"),                        "Which solver to use in g2o for matrix inversion: 'csparse' , 'cholmod' or 'pcg'");
00124 
00125   // Robot odometry options
00126   addOption("use_robot_odom",                static_cast<bool> (false),                 "In addition to frame-to-frame transformation use odometry information in the graph");
00127   addOption("use_robot_odom_only",           static_cast<bool> (false),                 "In addition to frame-to-frame transformation use odometry information in the graph");
00128   addOption("constrain_2d",                  static_cast<bool> (false),                 "Constrain camera motion to 2d plus heading");
00129   addOption("use_odom_for_prediction",       static_cast<bool> (false),                 "Use odometry information to predict feature locations. Do not use Kd-Tree anymore.");
00130   addOption("odometry_tpc",                  std::string("/odom"),                      "Robot odometry topic. Not required if odometry comes via /tf. Only the pose of the odometry is used.");
00131   addOption("odometry_information_factor",   static_cast<double> (1e4),                 "Diagonal coefficients of the information matrix of the odometry edges. Default: Std Dev of 0.01m and 0.01rad");
00132 
00133   // Visualization Settings 
00134   addOption("use_glwidget",                  static_cast<bool> (true),                  "3D view");
00135   addOption("use_gui",                       static_cast<bool> (true),                  "GUI vs Headless Mode");
00136   addOption("show_2d_display",               static_cast<bool> (true),                  "show or hide 2D view initially");
00137   addOption("glwidget_without_clouds",       static_cast<bool> (false),                 "3D view should only display the graph");
00138   addOption("visualize_mono_depth_overlay",  static_cast<bool> (false),                 "Show Depth and Monochrome image as overlay in featureflow");
00139   addOption("visualization_skip_step",       static_cast<int> (1),                      "Draw only every nth pointcloud row and line, high values require higher squared_meshing_threshold ");
00140   addOption("visualize_keyframes_only",      static_cast<bool> (false),                 "Do not render point cloud of non-keyframes.");
00141   addOption("fast_rendering_step",           static_cast<int> (1),                      "Draw only every nth pointcloud during user interaction");
00142   addOption("octomap_display_level",         static_cast<int> (16),                     "Show this level of OctoMap octree");
00143   addOption("gl_point_size",                 static_cast<double> (1.0),                 "Point size, when not triangulating. See documentation of GL_POINT_SIZE.");
00144   addOption("gl_grid_size_xy",               static_cast<int> (0),                      "Grid size in the xy plane (sidelength in number of cell). Zero disables. Note that this is in the coordinate system of the point cloud");
00145   addOption("gl_grid_size_xz",               static_cast<int> (20),                     "Grid size in the xz plane (sidelength in number of cell). Zero disables. Note that this is in the coordinate system of the point cloud");
00146   addOption("gl_grid_size_yz",               static_cast<int> (0),                      "Grid size in the yz plane (sidelength in number of cell). Zero disables. Note that this is in the coordinate system of the point cloud");
00147   addOption("gl_cell_size",                  static_cast<double> (1.0),                 "Grid cell size in meter.");
00148   addOption("squared_meshing_threshold",     static_cast<double> (0.0009),              "Don't triangulate over depth jumps. Should be increased with increasing visualization_skip_step");
00149   addOption("show_axis",                     static_cast<bool> (true),                  "Do/don't visualize the pose graph in glwidget");
00150   addOption("scalable_2d_display",           static_cast<bool> (false),                 "Whether the input images are expanded. Consumes CPU time");
00151   addOption("cloud_display_type",            static_cast<std::string>("POINTS"),        "Drastically affects rendering time. GL_xxx type of compiled list GL_TRIANGLE_STRIP (fastest processing of new clouds), GL_POINTS (fastest display) GL_TRIANGLES (no good), or ELLIPSOIDS (very slow, but visualizes standard deviation)");
00152 
00153   // Misc 
00154   addOption("start_paused",                  static_cast<bool> (false),                  "Whether to directly start mapping with the first input image, or to wait for the user to start manually");
00155   addOption("batch_processing",              static_cast<bool> (false),                 "Store results and close after bagfile has been processed");
00156   addOption("concurrent_node_construction",  static_cast<bool> (true),                  "Detect+extract features for new frame, while current frame is inserted into graph ");
00157   addOption("concurrent_edge_construction",  static_cast<bool> (true),                  "Compare current frame to many predecessors in parallel. Note that SIFTGPU matcher and GICP are mutex'ed for thread-safety");
00158   addOption("concurrent_io",                 static_cast<bool> (true),                  "Whether saving/sending should be done in background threads.");
00159   addOption("voxelfilter_size",              static_cast<double> (-1.0),                "In meter voxefilter displayed and stored pointclouds, useful to reduce the time for, e.g., octomap generation. Set negative to disable");
00160   addOption("nn_distance_ratio",             static_cast<double> (0.95),                "Feature correspondence is valid if distance to nearest neighbour is smaller than this parameter times the distance to the 2nd neighbour. This needs to be 0.9-1.0 for ORB and SIFTGPU w/ FLANN, since SIFTGPU Features are normalized and ORB become ambiguous for blurry images. For SURF and SIFT (CPU) use 0.5-0.8");
00161   addOption("keep_all_nodes",                static_cast<bool> (false),                 "Keep all nodes with 'no motion' assumption");
00162   addOption("keep_good_nodes",               static_cast<bool> (false),                 "Keep nodes without transformation estimation but enough features (according to min_matches) with 'no motion' assumption. These are not rendered in visualization.");
00163   addOption("clear_non_keyframes",           static_cast<bool> (false),                 "Remove the net data of nodes when it becomes clear that they will not be used as keyframe. However, this makes matching against them impossible.");
00164   addOption("min_time_reported",             static_cast<double> (-1.0),                "For easy profiling. Negative: nothing should be reported");
00165   addOption("preserve_raster_on_save",       static_cast<bool> (false),                 "Filter NaNs when saving clouds, destroying the image raster");
00166   addOption("skip_first_n_frames",           static_cast<int> (0),                      "Useful to skip start of a bagfile");
00167   addOption("segment_to_optimize",           static_cast<int> (-1),                     "If segment information is available, optimize with higher weights on this segment (set negative to disable)");
00168   addOption("send_clouds_delay",             static_cast<double> (-10.0),                "If set, wait with sending clouds until they are x seconds old (uses the clouds timestamp).");
00169   addOption("save_octomap_delay",            static_cast<double> (10.0),                "If set, wait with sending clouds until they are x seconds old (uses the clouds timestamp).");
00170   //Debug
00171   addOption("show_cloud_with_id",            static_cast<int> (-1),                     "Show only one cloud (namely that perceived at the respective node id");
00172   addOption("use_error_shortcut",            static_cast<bool> (true),                  "Compute isotropic bounds first in inlier determination");
00173 }
00174 
00175 
00176 ParameterServer::ParameterServer() {
00177   pre = ros::this_node::getName();
00178   pre += "/config/";
00179 
00180   defaultConfig();
00181   getValues();
00182 }
00183 
00184 ParameterServer* ParameterServer::instance() {
00185   if (_instance == NULL) {
00186     _instance = new ParameterServer();
00187   }
00188   return _instance;
00189 }
00190 
00191 void ParameterServer::addOption(std::string name, boost::any value, std::string description){
00192     config[name] = value;
00193     descriptions[name] = description;
00194 }
00195 
00196 /* Used by GUI */
00197 std::string ParameterServer::getDescription(std::string param_name) {
00198   return descriptions[param_name];
00199 }
00200 
00201 void ParameterServer::getValues() {
00202   std::map<std::string, boost::any>::const_iterator itr;
00203   for (itr = config.begin(); itr != config.end(); ++itr) {
00204     std::string name = itr->first;
00205     if (itr->second.type() == typeid(std::string)) {
00206       config[name] = getFromParameterServer<std::string> (pre + name,
00207           boost::any_cast<std::string>(itr->second));
00208       ROS_DEBUG_STREAM("Value for " << name << ":             " << boost::any_cast<std::string>(itr->second));
00209     } else if (itr->second.type() == typeid(int)) {
00210       config[name] = getFromParameterServer<int> (pre + name,
00211           boost::any_cast<int>(itr->second));
00212       ROS_DEBUG_STREAM("Value for " << name << ":             " << boost::any_cast<int>(itr->second));
00213     } else if (itr->second.type() == typeid(double)) {
00214       config[name] = getFromParameterServer<double> (pre + name,
00215           boost::any_cast<double>(itr->second));
00216       ROS_DEBUG_STREAM("Value for " << name << ":             " << boost::any_cast<double>(itr->second));
00217     } else if (itr->second.type() == typeid(bool)) {
00218       config[name] = getFromParameterServer<bool> (pre + name,
00219           boost::any_cast<bool>(itr->second));
00220       ROS_DEBUG_STREAM("Value for " << name << ":             " << boost::any_cast<bool>(itr->second));
00221     }
00222   }
00223   checkValues();
00224 }
00225 
00226 void ParameterServer::checkValues() {
00227     if (get<std::string>("matcher_type").compare("SIFTGPU") == 0
00228             && get<bool>("concurrent_node_construction") == true) {
00229         config["concurrent_node_construction"] = static_cast<bool>(false);
00230         ROS_WARN("Cannot use concurrent node construction with SiftGPU matcher! 'concurrent_node_construction' was set to false. Everything should work fine, but the CPU-threading won't happen (because you are using the GPU instead).");
00231     }
00232 
00233     if (get<double>("voxelfilter_size") > 0 && get<double>("observability_threshold") > 0) {
00234         ROS_ERROR("You cannot use the voxelfilter (param: voxelfilter_size) in combination with the environment measurement model (param: observability_threshold)");
00235     }
00236     if (get<std::string>("matcher_type").compare("SIFTGPU") == 0
00237             && get<bool>("concurrent_edge_construction") == true) {
00238         config["concurrent_edge_construction"] = static_cast<bool>(false);
00239         ROS_WARN("Cannot use concurrent edge construction with SiftGPU matcher! 'concurrent_edge_construction' was set to false. Everything should work fine, but the CPU-threading won't happen (because you are using the GPU instead).");
00240     }
00241     if (get<double>("max_translation_meter") <= 0){
00242       double dInf = std::numeric_limits<double>::infinity();
00243       set("max_translation_meter", dInf);
00244     }
00245     if (get<double>("max_rotation_degree") <= 0){
00246       double dInf = std::numeric_limits<double>::infinity();
00247       set("max_rotation_degree", dInf);
00248     }
00249 }


rgbdslam_v2
Author(s): Felix Endres, Juergen Hess, Nikolas Engelhard
autogenerated on Thu Jun 6 2019 21:49:45