Project

General

Profile

Statistics
| Branch: | Revision:

root / rgbdslam / src / graph_manager.h @ 9240aaa3

History | View | Annotate | Download (7.18 KB)

1 9240aaa3 Alex
/* This file is part of RGBDSLAM.
2
 * 
3
 * RGBDSLAM is free software: you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License as published by
5
 * the Free Software Foundation, either version 3 of the License, or
6
 * (at your option) any later version.
7
 * 
8
 * RGBDSLAM is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 * GNU General Public License for more details.
12
 * 
13
 * You should have received a copy of the GNU General Public License
14
 * along with RGBDSLAM.  If not, see <http://www.gnu.org/licenses/>.
15
 */
16
17
18
/*
19
 * graph_manager.h
20
 *
21
 *  Created on: 19.01.2011
22
 *      Author: hess
23
 */
24
25
#ifndef GRAPH_MANAGER_H_
26
#define GRAPH_MANAGER_H_
27
28
#include <ros/ros.h>
29
#include <tf/transform_broadcaster.h>
30
#include "node.h"
31
#include <pcl/filters/voxel_grid.h>
32
#include <Eigen/Core>
33
#include <Eigen/Geometry>
34
#include <opencv2/core/core.hpp>
35
#include <opencv2/features2d/features2d.hpp>
36
#include <map>
37
#include <QObject>
38
#include <QString>
39
#include <QMatrix4x4>
40
#include <QList>
41
#include <QMutex>
42
43
#include <iostream>
44
#include <sstream>
45
#include <string>
46
#include <ctime>
47
#include <memory> //for auto_ptr
48
#include "parameter_server.h"
49
50
#include "g2o/core/graph_optimizer_sparse.h"
51
52
#include "g2o/core/hyper_dijkstra.h"
53
54
//#define ROSCONSOLE_SEVERITY_INFO
55
56
//!Computes a globally optimal trajectory from transformations between Node-pairs
57
class GraphManager : public QObject {
58
    Q_OBJECT
59
    Q_SIGNALS:
60
    ///Connect to this signal to get the transformation matrix from the last frame as QString
61
    void newTransformationMatrix(QString);
62
    void sendFinished();
63
    void setGUIInfo(QString message);
64
    void setGUIStatus(QString message);
65
    void setPointCloud(pointcloud_type * pc, QMatrix4x4 transformation);
66
    void updateTransforms(QList<QMatrix4x4>* transformations);
67
    void setGUIInfo2(QString message);
68
    void setGraphEdges(QList<QPair<int, int> >* edge_list);
69
    void deleteLastNode();
70
    void resetGLViewer();
71
    
72
    public Q_SLOTS:
73
    /// Start over with new graph
74
    void reset();
75
    ///iterate over all Nodes, sending their transform and pointcloud
76
    void sendAllClouds();
77
    ///Call saveIndividualCloudsToFile, as background thread if threaded=true and possible 
78
    void saveIndividualClouds(QString file_basename, bool threaded=true);
79
    ///Call saveAllCloudsToFile,  as background thread if threaded=true and possible 
80
    void saveAllClouds(QString filename, bool threaded=true);
81
    ///Throw the last node out, reoptimize
82
    void deleteLastFrame(); 
83
    void setMaxDepth(float max_depth);
84
    ///Save trajectory of computed motion and ground truth (if available)
85
    void saveTrajectory(QString filebasename);
86
    void cloudRendered(pointcloud_type const * pc);
87
    void optimizeGraph(int iter = -1);
88
    void printEdgeErrors(QString);
89
    void pruneEdgesWithErrorAbove(float);
90
    void sanityCheck(float);
91
92
    public:
93
    GraphManager(ros::NodeHandle);
94
    ~GraphManager();
95
96
    /// Add new node to the graph.
97
    /// Node will be included, if a valid transformation to one of the former nodes
98
    /// can be found. If appropriate, the graph is optimized
99
    /// graphmanager owns newNode after this call. Do no delete the object
100
    bool addNode(Node* newNode); 
101
102
    ///Draw the features's motions onto the canvas
103
    void drawFeatureFlow(cv::Mat& canvas, 
104
                         cv::Scalar line_color = cv::Scalar(255,0,0,0), 
105
                         cv::Scalar circle_color = cv::Scalar(0,0,255,0)); 
106
107
    bool isBusy();
108
    
109
    float Max_Depth;
110
    //void setMaxDepth(float max_depth);
111
    //!Warning: This is a dangerous way to save memory. Some methods will behave undefined after this.
112
    ///Notable exception: optimizeGraph()
113
    void deleteFeatureInformation();
114
protected:
115
    
116
    ///iterate over all Nodes, transform them to the fixed frame, aggregate and save
117
    void saveAllCloudsToFile(QString filename);
118
    ///iterate over all Nodes, save each in one pcd-file
119
    void saveIndividualCloudsToFile(QString filename);
120
    void pointCloud2MeshFile(QString filename, pointcloud_type full_cloud);
121
    std::vector < cv::DMatch > last_inlier_matches_;
122
    std::vector < cv::DMatch > last_matches_;
123
124
    /// The parameter max_targets determines how many potential edges are wanted
125
    /// max_targets < 0: No limit
126
    /// max_targets = 0: Compare to first frame only
127
    /// max_targets = 1: Compare to previous frame only
128
    /// max_targets > 1: Select intelligently
129
    QList<int> getPotentialEdgeTargets(const Node* new_node, int max_targets);
130
    
131
    //std::vector<int> getPotentialEdgeTargetsFeatures(const Node* new_node, int max_targets);
132
    
133
    bool addEdgeToG2O(const LoadedEdge3D& edge, bool good_edge, bool set_estimate=false);
134
135
136
    ///Send markers to visualize the graph edges (cam transforms) in rviz (if somebody subscribed)
137
    void visualizeGraphEdges() const;
138
    ///Send markers to visualize the graph nodes (cam positions) in rviz (if somebody subscribed)
139
    void visualizeGraphNodes() const;
140
    ///Send markers to visualize the graph ids in rviz (if somebody subscribed)
141
    void visualizeGraphIds() const;
142
        
143
    
144
    
145
    ///Send markers to visualize the last matched features in rviz (if somebody subscribed)
146
    void visualizeFeatureFlow3D(unsigned int marker_id = 0,
147
                                bool draw_outlier = true) const;
148
    ///Send the transform between openni_camera (the initial position of the cam)
149
    ///and the cumulative motion. 
150
    ///This is called periodically by a ros timer and after each optimizer run
151
    void broadcastTransform(const ros::TimerEvent& event);
152
    ///Constructs a list of transformation matrices from all nodes (used for visualization in glviewer)
153
    ///The object lives on the heap and needs to be destroyed somewhere else (i.e. in glviewer)
154
    QList<QMatrix4x4>* getAllPosesAsMatrixList();
155
    QList<QPair<int, int> >* getGraphEdges() const;
156
    void resetGraph();
157
158
    void mergeAllClouds(pointcloud_type & merge);
159
    double geodesicDiscount(g2o::HyperDijkstra& hypdij, const MatchingResult& mr);
160
    
161
    g2o::SparseOptimizer* optimizer_;
162
163
    ros::Publisher marker_pub_; 
164
    ros::Publisher ransac_marker_pub_;
165
    ros::Publisher whole_cloud_pub_;
166
    ros::Publisher batch_cloud_pub_;
167
    
168
    //!Used to start the broadcasting of the pose estimate regularly
169
    ros::Timer timer_;
170
    //!Used to broadcast the pose estimate
171
    tf::TransformBroadcaster br_;
172
    tf::Transform computed_motion_; ///<transformation of the last frame to the first frame (assuming the first one is fixed)
173
    tf::Transform  init_base_pose_;
174
    tf::Transform base2points_;//base_frame -> optical_frame 
175
    //Eigen::Matrix4f latest_transform_;///<same as computed_motion_ as Eigen
176
    QMatrix4x4 latest_transform_;///<same as computed_motion_ as Eigen
177
178
179
    //!Map from node id to node. Assumption is, that ids start at 0 and are consecutive
180
    std::map<int, Node* > graph_;
181
    bool reset_request_;
182
    unsigned int marker_id;
183
    int last_matching_node_;
184
    g2o::SE3Quat last_edge_;
185
    bool batch_processing_runs_;
186
    bool process_node_runs_;
187
    QMutex optimizer_mutex;
188
    //cv::FlannBasedMatcher global_flann_matcher;
189
    
190
};
191
192
193
194
#endif /* GRAPH_MANAGER_H_ */