00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef RGBD_SLAM_NODE_H_
00019 #define RGBD_SLAM_NODE_H_
00020
00021
00022 #include "ros/ros.h"
00023 #include <vector>
00024 #include <opencv2/core/core.hpp>
00025 #include <opencv2/features2d/features2d.hpp>
00026 #include <Eigen/Core>
00027
00028 #include <sensor_msgs/PointCloud2.h>
00029 #include <sensor_msgs/CameraInfo.h>
00030 #include <pcl/registration/icp.h>
00031 #include <pcl/registration/registration.h>
00032 #include "parameter_server.h"
00033
00034 #include <tf/transform_datatypes.h>
00035 #include <QMutex>
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifdef USE_ICP_BIN
00046 #include "gicp-fallback.h"
00047 #endif
00048
00049 #ifdef USE_ICP_CODE
00050 #include "gicp/gicp.h"
00051 #include "gicp/transform.h"
00052 #endif
00053
00054 #include "matching_result.h"
00055 #include <Eigen/StdVector>
00056
00058 class Node {
00059 public:
00063 Node(const cv::Mat& visual,
00064 const cv::Mat& depth,
00065 const cv::Mat& detection_mask,
00066 const sensor_msgs::CameraInfoConstPtr& cam_info,
00067 std_msgs::Header depth_header,
00068 cv::Ptr<cv::FeatureDetector> detector,
00069 cv::Ptr<cv::DescriptorExtractor> extractor);
00073 Node(const cv::Mat visual,
00074 cv::Ptr<cv::FeatureDetector> detector,
00075 cv::Ptr<cv::DescriptorExtractor> extractor,
00076 pointcloud_type::Ptr point_cloud,
00077 const cv::Mat detection_mask = cv::Mat());
00078
00079 Node(){}
00081 ~Node();
00082
00084 MatchingResult matchNodePair(const Node* older_node);
00085
00086
00088 void setOdomTransform(tf::StampedTransform odom);
00090 void setGroundTruthTransform(tf::StampedTransform gt);
00092 void setBase2PointsTransform(tf::StampedTransform& b2p);
00094 tf::StampedTransform getOdomTransform();
00096 tf::StampedTransform getGroundTruthTransform();
00098 tf::StampedTransform getBase2PointsTransform();
00099
00101 bool getRelativeTransformationTo(const Node* target_node,
00102 std::vector<cv::DMatch>* initial_matches,
00103 Eigen::Matrix4f& resulting_transformation,
00104 float& rmse,
00105 std::vector<cv::DMatch>& matches) const;
00106
00107 #ifdef USE_ICP_BIN
00108
00109
00110 bool getRelativeTransformationTo_ICP_bin(const Node* target_node,Eigen::Matrix4f& transformation,
00111 const Eigen::Matrix4f* initial_transformation = NULL);
00112 #endif
00113
00114
00116 void publish(ros::Time timestamp, ros::Publisher pub);
00117
00118 void buildFlannIndex();
00121 unsigned int featureMatching(const Node* other, std::vector<cv::DMatch>* matches) const;
00122
00123 #ifdef USE_ICP_CODE
00124 bool getRelativeTransformationTo_ICP_code(const Node* target_node,
00125 Eigen::Matrix4f& transformation,
00126 const Eigen::Matrix4f& initial_transformation);
00127
00128 static const double gicp_epsilon = 1e-4;
00129 static const double gicp_d_max = 0.20;
00130 static const int gicp_max_iterations = 10;
00131 static const int gicp_min_point_cnt = 100;
00132
00133 bool gicp_initialized;
00134 void Eigen2GICP(const Eigen::Matrix4f& m, dgc_transform_t g_m);
00135 void GICP2Eigen(const dgc_transform_t g_m, Eigen::Matrix4f& m);
00136 void gicpSetIdentity(dgc_transform_t m);
00137 dgc::gicp::GICPPointSet* getGICPStructure(unsigned int max_count = 0) const;
00138 void clearGICPStructure() const;
00139 protected:
00140 mutable dgc::gicp::GICPPointSet* gicp_point_set_;
00141
00142 public:
00143 #endif
00144
00145 void clearFeatureInformation();
00146 void addPointCloud(pointcloud_type::Ptr pc_col);
00147
00148
00150 void clearPointCloud();
00151
00153 unsigned int id_;
00154 pointcloud_type::Ptr pc_col;
00156 cv::Mat feature_descriptors_;
00157
00159 std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> > feature_locations_3d_;
00160 std::vector<float> siftgpu_descriptors;
00161
00163 std::vector<cv::KeyPoint> feature_locations_2d_;
00165 std::vector<std::pair<float, float> > feature_depth_stats_;
00166
00167
00168
00169
00170 protected:
00171 static QMutex gicp_mutex;
00172 static QMutex siftgpu_mutex;
00173 cv::flann::Index* flannIndex;
00174 tf::StampedTransform base2points_;
00175 tf::StampedTransform ground_truth_transform_;
00176 tf::StampedTransform odom_transform_;
00177 int initial_node_matches_;
00178
00179
00180 #ifdef USE_SIFT_GPU
00181
00182 void projectTo3DSiftGPU(std::vector<cv::KeyPoint>& feature_locations_2d,
00183 std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >& feature_locations_3d,
00184 const pointcloud_type::Ptr point_cloud,
00185 std::vector<float>& descriptors_in, cv::Mat& descriptors_out);
00187 void projectTo3DSiftGPU(std::vector<cv::KeyPoint>& feature_locations_2d,
00188 std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >& feature_locations_3d,
00189 const cv::Mat& depth,
00190 const sensor_msgs::CameraInfoConstPtr& cam_info,
00191 std::vector<float>& descriptors_in, cv::Mat& descriptors_out);
00192 #endif
00193
00194 void projectTo3D(std::vector<cv::KeyPoint>& feature_locations_2d,
00195 std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >& feature_locations_3d,
00196 const pointcloud_type::ConstPtr point_cloud);
00198 void projectTo3D(std::vector<cv::KeyPoint>& feature_locations_2d,
00199 std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >& feature_locations_3d,
00200 const cv::Mat& depth,
00201 const sensor_msgs::CameraInfoConstPtr& cam_info);
00202
00203
00204 template<class CONTAINER>
00205 Eigen::Matrix4f getTransformFromMatchesUmeyama(const Node* other_node, CONTAINER matches) const;
00206
00207
00208 template<class CONTAINER>
00209 Eigen::Matrix4f getTransformFromMatches(const Node* other_node,
00210 const CONTAINER & matches,
00211 bool& valid,
00212 float max_dist_m = -1) const;
00213
00214
00215
00217 void mat2dist(const Eigen::Matrix4f& t, double &dist){
00218 dist = sqrt(t(0,3)*t(0,3)+t(1,3)*t(1,3)+t(2,3)*t(2,3));
00219 }
00220
00221
00223 void retrieveBase2CamTransformation();
00224
00225 template<class CONTAINER>
00226 void computeInliersAndError(const CONTAINER & initial_matches,
00227 const Eigen::Matrix4f& transformation,
00228 const std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >& origins,
00229 const std::vector<std::pair<float, float> > origins_depth_stats,
00230 const std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >& targets,
00231 const std::vector<std::pair<float, float> > targets_depth_stats,
00232 std::vector<cv::DMatch>& new_inliers,
00233 double& mean_error, std::vector<double>& errors,
00234 double squaredMaxInlierDistInM = 0.0009) const;
00235
00236 public:
00237 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00238 };
00239 #endif