graph_manager.h
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 
00017 
00018 /*
00019  * graph_manager.h
00020  *
00021  *  Created on: 19.01.2011
00022  *      Author: hess
00023  */
00024 
00025 #ifndef GRAPH_MANAGER_H_
00026 #define GRAPH_MANAGER_H_
00027 
00028 #include <ros/ros.h>
00029 #include <tf/transform_broadcaster.h>
00030 #include "node.h"
00031 #include "ColorOctomapServer.h"
00032 #include <Eigen/Core>
00033 #include <Eigen/Geometry>
00034 #include <opencv2/core/core.hpp>
00035 #include <opencv2/features2d/features2d.hpp>
00036 #include <map>
00037 #include <QObject>
00038 #include <QString>
00039 #include <QMatrix4x4>
00040 #include <QList>
00041 #include <QMap>
00042 #include <QMutex>
00043 
00044 #include <iostream>
00045 #include <sstream>
00046 #include <string>
00047 #include <ctime>
00048 #include <memory> //for auto_ptr
00049 #include <utility>
00050 #include "parameter_server.h"
00051 // #define DO_LOOP_CLOSING
00052 // DO_FEATURE_OPTIMIZATION is set in CMakeLists.txt
00053 #ifdef DO_FEATURE_OPTIMIZATION
00054 #include "landmark.h"
00055 #endif
00056 
00057 //#include "g2o/core/graph_optimizer_sparse.h"
00058 #include "g2o/core/sparse_optimizer.h"
00059 
00060 //#include "g2o/types/slam3d/camera_parameters.h"
00061 #include "g2o/types/slam3d/parameter_camera.h"
00062 #include "g2o/types/slam2d/vertex_se2.h"
00063 
00064 #include "g2o/core/hyper_dijkstra.h"
00065 #include "g2o/core/robust_kernel_impl.h"
00066 
00067 namespace tf {
00068 class TransformListener;
00069 }
00070 
00071 //typedef g2o::HyperGraph::VertexSet::iterator Vset_it;
00073 typedef std::map<int, Node* >::iterator graph_it;
00074 typedef std::set<g2o::HyperGraph::Edge*> EdgeSet;
00075 typedef g2o::HyperGraph::EdgeSet::iterator EdgeSet_it;
00076 typedef std::map<int, Node* >::iterator graph_it;
00077 //#define ROSCONSOLE_SEVERITY_INFO
00078 /*
00079 class GraphNode {
00080   GraphNode() : backend_node(NULL), frontend_node(NULL), index(-1) {}
00081 
00082   g2o::VertexSE3* backend_node;
00083   Node* frontend_node;
00084   int index;
00085 }
00086 */
00087 
00089 class GraphManager : public QObject {
00090     Q_OBJECT
00091     Q_SIGNALS:
00093       void newTransformationMatrix(QString);
00094       void sendFinished();
00095       void setGUIInfo(QString message);
00096       void setGUIStatus(QString message);
00097       void setPointCloud(pointcloud_type * pc, QMatrix4x4 transformation);
00098       void setFeatures(const std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >*);
00099       void updateTransforms(QList<QMatrix4x4>* transformations);
00100       void setGUIInfo2(QString message);
00101       void setGraphEdges(const QList<QPair<int, int> >* edge_list);
00102       void deleteLastNode();
00103       void resetGLViewer();
00104       void setGraph(const g2o::OptimizableGraph*);
00105       void iamBusy(int id, const char* message, int max);
00106       void progress(int id, const char* message, int val);
00107       void renderableOctomap(Renderable* r);
00108     
00109     public Q_SLOTS:
00111       void reset();
00113       void deleteLastFrame(); 
00114       void clearPointCloud(pointcloud_type const * pc);
00115       void clearPointClouds();
00116       void reducePointCloud(pointcloud_type const * pc);
00119       double optimizeGraph(double iter = -1, bool nonthreaded=false);
00120       void printEdgeErrors(QString);
00124       unsigned int pruneEdgesWithErrorAbove(float);
00125       void sanityCheck(float);
00126       void toggleMapping(bool);
00127       void filterNodesByPosition(float x, float y, float z);
00128 
00129       //The following SLOT methods are in graph_mgr_io.cpp:
00131       void sendAllClouds(bool threaded_if_available=true);
00134       void saveBagfileAsync(QString filename);
00136       void saveBagfile(QString filename);
00138       void saveIndividualClouds(QString file_basename, bool threaded=true);
00140       void saveAllClouds(QString filename, bool threaded=true);
00142       void saveAllFeatures(QString filename, bool threaded = true);
00144       void saveOctomap(QString filename, bool threaded = true);
00146       void saveTrajectory(QString filebasename, bool with_ground_truth = false);
00148       void saveG2OGraph(QString filename);
00150       void occupancyFilterClouds();
00151 
00152     public:
00153       GraphManager();
00154       ~GraphManager();
00155 
00161     bool addNode(Node* newNode); 
00162 
00165     void addOdometry(ros::Time timestamp, tf::TransformListener* listener);
00171     bool nodeComparisons(Node* newNode, 
00172                          QMatrix4x4& curr_motion_estimate,
00173                          bool& edge_to_keyframe);
00174 
00175     void firstNode(Node* new_node);
00176 
00178     g2o::HyperGraph::VertexSet camera_vertices;
00180     g2o::HyperGraph::EdgeSet cam_cam_edges_;
00183     //g2o::HyperGraph::EdgeSet dummy_edges_; 
00185     g2o::HyperGraph::EdgeSet odometry_edges_;
00186     g2o::HyperGraph::EdgeSet current_match_edges_;
00187 
00188 #ifdef DO_FEATURE_OPTIMIZATION
00189     g2o::HyperGraph::EdgeSet cam_lm_edges;
00190     g2o::HyperGraph::VertexSet landmark_vertices;
00191 #endif
00192 
00194     void drawFeatureFlow(cv::Mat& canvas,
00195                          cv::Scalar line_color = cv::Scalar(255,0,0,0), 
00196                          cv::Scalar circle_color = cv::Scalar(0,0,255,0)); 
00197 
00198     //Juergen: overloading function to draw features in different image
00199     void drawFeatureFlow(cv::Mat& canvas_flow, cv::Mat& canvas_features,
00200                          cv::Scalar line_color = cv::Scalar(255,0,0,0), 
00201                          cv::Scalar circle_color = cv::Scalar(0,0,255,0)); 
00202 
00204     bool isBusy();
00205     
00208     void deleteFeatureInformation();
00210     void writeOctomap(QString filename) const;
00211     void setOptimizerVerbose(bool verbose);
00212 
00215     void setEmpiricalCovariances();
00216 protected:
00217         
00219     void resetGraph();
00221     double optimizeGraphImpl(double max_iter);
00222 
00225     bool updateCloudOrigin(Node* node);
00227     void createOptimizer(std::string backend, g2o::SparseOptimizer* optimizer = NULL);
00229     MatchingResult curr_best_result_; 
00230 
00232     tf::StampedTransform computeFixedToBaseTransform(Node* node, bool invert);
00237     QList<int> getPotentialEdgeTargetsWithDijkstra(const Node* new_node, int sequential_targets, int geodesic_targets, int sampled_targets = 5, int predecessor_id = -1, bool include_predecessor = false);
00238     
00239     //std::vector<int> getPotentialEdgeTargetsFeatures(const Node* new_node, int max_targets);
00240 
00242     void localizationUpdate(Node* new_node, QMatrix4x4 motion_estimate);
00243 #ifdef DO_FEATURE_OPTIMIZATION
00244     std::vector<Landmark> landmarks;
00245     void updateLandmarks(const MatchingResult& match_result, Node* old_node, Node* new_node);
00246     int next_landmark_id;
00247     // merge lm_2 into lm_1
00248     void mergeLandmarks(Landmark *lm_1, Landmark *lm_2);
00249     void printLandmarkStatistic();
00250     void updateProjectionEdges();
00251     void updateLandmarkInGraph(Landmark* lm);
00252     void removeFeaturesFromGraph();
00253 #endif
00254 
00255 
00256 #ifdef DO_LOOP_CLOSING
00257     void createSearchTree(); // use all images in the GraphManager
00258     void createSearchTree(const std::vector<int>& node_ids); // as stored in GraphManager::graph_
00259     // find nodes with similar images, returns sorted list of images with their score (more is better)
00260     void getNeighbours(int node_id, uint neighbour_cnt, std::vector<std::pair<int,float> >& neighbours);
00261 
00262     cv::flann::Index *tree;
00263     cv::Mat all_descriptors;
00264 
00265     std::set<std::pair<int,int> > tested_pairs;
00266     std::set<std::pair<int,int> > matched_pairs;
00267 
00268     void loopClosingTest();
00269     uint descriptor_length;
00270     uint total_descriptor_count;
00271     int *descriptor_to_node;
00272 #endif
00273     
00275     bool addEdgeToG2O(const LoadedEdge3D& edge, Node* n1, Node* n2, bool good_edge, bool set_estimate, QMatrix4x4& motion_estimate);
00277     bool addOdometryEdgeToG2O(const LoadedEdge3D& edge, Node* n1, Node* n2, QMatrix4x4& motion_estimate);
00278 
00279     //Delete a camera frame. Be careful, this might split the graph!
00280     void deleteCameraFrame(int id);
00281 
00283     void broadcastTransform(const tf::StampedTransform& computed_motion);
00284 
00286     void broadcastLatestTransform(const ros::TimerEvent& event) const;
00287 
00290     tf::StampedTransform stampedTransformInWorldFrame(const Node* node, 
00291                                                       const tf::Transform& computed_motion) const;
00292 
00294     void addKeyframe(int id);
00295 
00296     int last_added_cam_vertex_id(){
00297       return graph_[graph_.size()-1]->vertex_id_;
00298     }
00299 
00300     int nodeId2VertexId(int node_id){
00301      assert(graph_.find(node_id) != graph_.end());
00302      return graph_[node_id]->vertex_id_;
00303     }
00305     QList<QMatrix4x4>* getAllPosesAsMatrixList() const;
00307     QList<QPair<int, int> >* getGraphEdges(); 
00308 
00309     // MEMBER VARIABLES
00310     QList<QPair<int, int> > current_edges_;
00311     //QMutex current_edges_lock_;
00312     //QList<QMatrix4x4> current_poses_;
00313 
00314     //void mergeAllClouds(pointcloud_type & merge);
00315     double geodesicDiscount(g2o::HyperDijkstra& hypdij, const MatchingResult& mr);
00317     void setEmpiricalCovariancesForEdgeSet(EdgeSet& edges);
00318     
00319     g2o::SparseOptimizer* optimizer_;
00320 
00321     ros::Publisher marker_pub_; 
00322     ros::Publisher ransac_marker_pub_;
00323     ros::Publisher whole_cloud_pub_;
00324     ros::Publisher batch_cloud_pub_;
00325     ros::Publisher online_cloud_pub_;
00326     
00328     ros::Timer timer_;
00330     mutable tf::TransformBroadcaster br_;
00331     tf::Transform computed_motion_; 
00332     tf::Transform  init_base_pose_;
00333     tf::StampedTransform latest_transform_cache_;//base_frame -> optical_frame 
00334 
00336     typedef std::pair<int, Node*> GraphNodeType;
00337     //QMap<int, Node* > graph_;
00338     std::map<int, Node* > graph_;
00339     bool reset_request_;
00340     unsigned int marker_id_;
00341     bool batch_processing_runs_;
00342     bool process_node_runs_;
00343     bool localization_only_;
00345     QMutex optimizer_mutex_;
00347     QMutex optimization_mutex_;
00348     //cv::FlannBasedMatcher global_flann_matcher;
00349     QList<int> keyframe_ids_;//Keyframes are added, if no previous keyframe was matched
00350     //NEW std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> > feature_coords_;  
00351     //NEW cv::Mat feature_descriptors_;         
00352     unsigned int loop_closures_edges, sequential_edges;
00353     unsigned int next_seq_id;
00354     unsigned int next_vertex_id;
00355     std::string current_backend_;
00356     int earliest_loop_closure_node_;
00357     ColorOctomapServer co_server_;
00358     
00359     //The following methods are defined in graph_mgr_io.cpp:
00360     void sendAllCloudsImpl();
00362     void saveAllCloudsToFile(QString filename);
00364     void saveAllFeaturesToFile(QString filename);
00366     void saveIndividualCloudsToFile(QString filename);
00367     void saveOctomapImpl(QString filename);
00368     void renderToOctomap(Node* node);
00369     void pointCloud2MeshFile(QString filename, pointcloud_type full_cloud);
00370     void savePlyFile(QString filename, pointcloud_normal_type& full_cloud);
00371 
00372     //RVIZ visualization stuff (also in graph_mgr_io.cpp)
00374     void visualizeGraphEdges() const;
00376     void visualizeGraphNodes() const;
00378     void visualizeGraphIds() const;
00380     void visualizeFeatureFlow3D(unsigned int marker_id = 0, bool draw_outlier = true);
00381     
00382     g2o::RobustKernelHuber robust_kernel_;
00383     //g2o::RobustKernelDCS robust_kernel_;
00384     g2o::SparseOptimizer::Vertex* calibration_vertex_;
00385     //g2o::SparseOptimizer::Vertex* odom_calibration_vertex_;
00386 
00387 
00388     //Odometry variables needed
00389     unsigned int last_odom_time_;
00390 
00391 };
00392 
00394 void publishCloud(Node* node, ros::Time timestamp, ros::Publisher pub);
00395 
00396 
00397 #endif /* GRAPH_MANAGER_H_ */


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