00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <vslam_system/vslam.h>
00036 #include <cstdio>
00037
00038
00039 using namespace sba;
00040 using namespace pcl;
00041
00042 namespace vslam {
00043
00044 VslamSystem::VslamSystem(const std::string& vocab_tree_file, const std::string& vocab_weights_file,
00045 int min_keyframe_inliers, double min_keyframe_distance, double min_keyframe_angle)
00046 : frame_processor_(10),
00047 #ifdef HOWARD
00048 vo_(boost::shared_ptr<pe::PoseEstimator>(new pe::PoseEstimatorH(10, true, 6.0, 4.0, 4.0, 0.05, 10, 17)),
00049 #else
00050 vo_(boost::shared_ptr<pe::PoseEstimator>(new pe::PoseEstimator3d(1000,true,6.0,8.0,8.0)),
00051 #endif
00052 40, 10, min_keyframe_inliers, min_keyframe_distance, min_keyframe_angle),
00053 place_recognizer_(vocab_tree_file, vocab_weights_file),
00054 #ifdef HOWARD
00055 pose_estimator_(10, true, 6.0, 8.0, 8.0, 0.05, 10, 17)
00056 #else
00057 pose_estimator_(5000, true, 10.0, 3.0, 3.0)
00058 #endif
00059 {
00060 sba_.useCholmod(true);
00062 pose_estimator_.wx = 92;
00063 pose_estimator_.wy = 48;
00064
00065
00066
00067 prInliers = 200;
00068 numPRs = 0;
00069 nSkip = 20;
00070 doPointPlane = true;
00071 }
00072
00073 bool VslamSystem::addFrame(const frame_common::CamParams& camera_parameters,
00074 const cv::Mat& left, const cv::Mat& right, int nfrac,
00075 bool setPointCloud)
00076 {
00077
00078 frame_common::Frame next_frame;
00079 next_frame.setCamParams(camera_parameters);
00080 frame_processor_.setStereoFrame(next_frame, left, right, nfrac, setPointCloud);
00081 next_frame.frameId = sba_.nodes.size();
00082 #ifndef HOWARD
00083 next_frame.img = cv::Mat();
00084 #endif
00085 next_frame.imgRight = cv::Mat();
00086
00087 if (setPointCloud && pointcloud_processor_ && doPointPlane)
00088 {
00089 pointcloud_processor_->setPointcloud(next_frame, next_frame.dense_pointcloud);
00090 printf("[Pointcloud] set a pointcloud! %d\n", (int)next_frame.pointcloud.points.size());
00091 }
00092
00093
00094 bool is_keyframe = vo_.addFrame(next_frame);
00095
00096
00097 if (is_keyframe)
00098 {
00099 addKeyframe(next_frame);
00100 }
00101
00102 if (frames_.size() > 1 && vo_.pose_estimator_->inliers.size() < 40)
00103 std::cout << std::endl << "******** Bad image match: " << vo_.pose_estimator_->inliers.size()
00104 << " inliers" << std::endl << std::endl;
00105
00106 return is_keyframe;
00107 }
00108
00109 bool VslamSystem::addFrame(const frame_common::CamParams& camera_parameters,
00110 const cv::Mat& left, const cv::Mat& right,
00111 const pcl::PointCloud<PointXYZRGB>& ptcloud, int nfrac)
00112 {
00113
00114 frame_common::Frame next_frame;
00115 next_frame.setCamParams(camera_parameters);
00116 frame_processor_.setStereoFrame(next_frame, left, right, nfrac);
00117 next_frame.frameId = sba_.nodes.size();
00118 #ifndef HOWARD
00119 next_frame.img = cv::Mat();
00120 #endif
00121 next_frame.imgRight = cv::Mat();
00122 if (pointcloud_processor_ && doPointPlane)
00123 {
00124 pointcloud_processor_->setPointcloud(next_frame, ptcloud);
00125 printf("[Pointcloud] set a pointcloud! %d\n", (int)next_frame.pointcloud.points.size());
00126 }
00127
00128
00129 bool is_keyframe = vo_.addFrame(next_frame);
00130
00131
00132 if (is_keyframe)
00133 {
00134 addKeyframe(next_frame);
00135
00136 frames_.back().dense_pointcloud = ptcloud;
00137 }
00138
00139 if (frames_.size() > 1 && vo_.pose_estimator_->inliers.size() < 40)
00140 std::cout << std::endl << "******** Bad image match: " << std::endl << std::endl;
00141
00142 return is_keyframe;
00143 }
00144
00145 void VslamSystem::addKeyframe(frame_common::Frame& next_frame)
00146 {
00147 frames_.push_back(next_frame);
00148 vo_.doPointPlane = doPointPlane;
00149 vo_.transferLatestFrame(frames_, sba_);
00150
00151
00152 frame_common::Frame& transferred_frame = frames_.back();
00153
00154
00155
00156 std::vector<const frame_common::Frame*> place_matches;
00157 const size_t N = 5;
00158 place_recognizer_.findAndInsert(transferred_frame, transferred_frame.frameId, frames_, N, place_matches);
00159 printf("PLACEREC: Found %d matches\n", (int)place_matches.size());
00160
00161 for (int i = 0; i < (int)place_matches.size(); ++i)
00162 {
00163 frame_common::Frame& matched_frame = const_cast<frame_common::Frame&>(*place_matches[i]);
00164
00165
00166 if (matched_frame.frameId >= (int)frames_.size() - nSkip - 1)
00167 {
00168
00169 continue;
00170 }
00171
00172
00173 int inliers = pose_estimator_.estimate(matched_frame, transferred_frame);
00174 printf("\tMatch %d: %d inliers, frame index %d\n", i, inliers, matched_frame.frameId);
00175 if (inliers > prInliers)
00176 {
00177 numPRs++;
00178
00179 printf("\t[PlaceRec] Adding PR link between frames %d and %d\n", transferred_frame.frameId,
00180 matched_frame.frameId);
00181
00182
00183 Matrix<double,3,4> frame_to_world;
00184 Node &matched_node = sba_.nodes[matched_frame.frameId];
00185 Quaterniond fq0;
00186 fq0 = matched_node.qrot;
00187 transformF2W(frame_to_world, matched_node.trans, fq0);
00188
00189 addProjections(matched_frame, transferred_frame, frames_, sba_, pose_estimator_.inliers,
00190 frame_to_world, matched_frame.frameId, transferred_frame.frameId);
00191
00192
00193 if (pointcloud_processor_ && doPointPlane)
00194 {
00195 printf("\t[PlaceRec] Adding in point cloud projections\n");
00196 Matrix<double,3,4> f2w_transferred;
00197 Node &transferred_node = sba_.nodes[transferred_frame.frameId];
00198 transformF2W(f2w_transferred,transferred_node.trans,transferred_node.qrot);
00199 pointcloud_processor_->match(matched_frame, transferred_frame, pose_estimator_.trans, Quaterniond(pose_estimator_.rot), pointcloud_matches_);
00200 addPointCloudProjections(matched_frame, transferred_frame, sba_, pointcloud_matches_,
00201 frame_to_world, f2w_transferred, matched_frame.frameId, transferred_frame.frameId);
00202 }
00203
00204 double cst = sba_.calcRMSCost();
00205 cout << endl << "*** RMS Cost: " << cst << endl << endl;
00206
00207 if (cst > 4.0)
00208 {
00209
00210 int n = sba_.nodes.size();
00211 n = n-50;
00212 if (n < 1) n=1;
00213 sba_.nFixed = n;
00214 sba_.doSBA(3,1.0e-4, SBA_SPARSE_CHOLESKY);
00215
00216 sba_.nFixed = 1;
00217 }
00218 }
00219 }
00220 }
00221
00222 void VslamSystem::refine(int initial_runs)
00223 {
00225
00226 sba_.doSBA(initial_runs, 1.0e-4, SBA_SPARSE_CHOLESKY);
00227 if (sba_.calcRMSCost() > 4.0)
00228 sba_.doSBA(10, 1.0e-4, SBA_SPARSE_CHOLESKY);
00229 if (sba_.calcRMSCost() > 4.0)
00230 sba_.doSBA(10, 1.0e-4, SBA_SPARSE_CHOLESKY);
00231 }
00232
00233 }