00001 #include <Eigen/Eigen>
00002 #include <ndt_registration/ndt_matcher_d2d_feature.h>
00003 #include <boost/bind.hpp>
00004 #include <sys/time.h>
00005
00006 namespace lslgeneric
00007 {
00008
00009 bool
00010 NDTMatcherFeatureD2D::covariance( NDTMap& targetNDT,
00011 NDTMap& sourceNDT,
00012 Eigen::Transform<double,3,Eigen::Affine,Eigen::ColMajor>& T,
00013 Eigen::Matrix<double,6,6> &cov)
00014 {
00015 assert(false);
00016 };
00017
00018
00019 double
00020 NDTMatcherFeatureD2D::scoreNDT(std::vector<NDTCell*> &sourceNDT, NDTMap &targetNDT,
00021 Eigen::Transform<double,3,Eigen::Affine,Eigen::ColMajor>& T)
00022 {
00023 NUMBER_OF_ACTIVE_CELLS = 0;
00024 double score_here = 0;
00025 double det = 0;
00026 bool exists = false;
00027 NDTCell *cell;
00028 Eigen::Matrix3d covCombined, icov;
00029 Eigen::Vector3d meanFixed;
00030 Eigen::Vector3d meanMoving;
00031 Eigen::Matrix3d R = T.rotation();
00032 std::vector<std::pair<unsigned int, double> > scores;
00033 for(unsigned int j=0; j<_corr.size(); j++)
00034 {
00035 unsigned int i = _corr[j].second;
00036 if (_corr[j].second >= (int)sourceNDT.size())
00037 {
00038 std::cout << "second correspondance : " << _corr[j].second << ", " << sourceNDT.size() << std::endl;
00039 }
00040 if (sourceNDT[i] == NULL)
00041 {
00042 std::cout << "sourceNDT[i] == NULL!" << std::endl;
00043 }
00044 meanMoving = T*sourceNDT[i]->getMean();
00045
00046 cell = targetNDT.getCellIdx(_corr[j].first);
00047 {
00048
00049 if(cell == NULL)
00050 {
00051 std::cout << "cell== NULL!!!" << std::endl;
00052 }
00053 else
00054 {
00055 if(cell->hasGaussian_)
00056 {
00057 meanFixed = cell->getMean();
00058 covCombined = cell->getCov() + R.transpose()*sourceNDT[i]->getCov()*R;
00059 covCombined.computeInverseAndDetWithCheck(icov,det,exists);
00060 if(!exists) continue;
00061 double l = (meanMoving-meanFixed).dot(icov*(meanMoving-meanFixed));
00062 if(l*0 != 0) continue;
00063 if(l > 120) continue;
00064
00065 double sh = -lfd1*(exp(-lfd2*l/2));
00066
00067 if(fabsf(sh) > 1e-10)
00068 {
00069 NUMBER_OF_ACTIVE_CELLS++;
00070 }
00071 scores.push_back(std::pair<unsigned int, double>(j, sh));
00072 score_here += sh;
00073
00074 }
00075 }
00076 }
00077 }
00078
00079 if (_trimFactor == 1.)
00080 {
00081 return score_here;
00082 }
00083 else
00084 {
00085
00086 if (scores.empty())
00087 return score_here;
00088
00089 score_here = 0.;
00090 unsigned int index = static_cast<unsigned int>(_trimFactor * (scores.size() - 1));
00091
00092 std::nth_element (scores.begin(), scores.begin()+index, scores.end(), boost::bind(&std::pair<unsigned int, double>::second, _1) < boost::bind(&std::pair<unsigned int, double>::second, _2));
00093 std::fill(_goodCorr.begin(), _goodCorr.end(), false);
00094
00095 for (unsigned int i = 0; i < _goodCorr.size(); i++)
00096 {
00097 if (i <= index)
00098 {
00099 score_here += scores[i].second;
00100 _goodCorr[scores[i].first] = true;
00101 }
00102 }
00103 return score_here;
00104 }
00105 }
00106
00107 double
00108 NDTMatcherFeatureD2D::derivativesNDT(
00109 const std::vector<NDTCell*> &sourceNDT,
00110 const NDTMap &targetNDT,
00111 Eigen::MatrixXd &score_gradient,
00112 Eigen::MatrixXd &Hessian,
00113 bool computeHessian
00114 )
00115 {
00116
00117 struct timeval tv_start, tv_end;
00118 double score_here = 0;
00119
00120 gettimeofday(&tv_start,NULL);
00121 NUMBER_OF_ACTIVE_CELLS = 0;
00122 score_gradient.setZero();
00123 Hessian.setZero();
00124
00125 pcl::PointXYZ point;
00126 Eigen::Vector3d transformed;
00127 Eigen::Vector3d meanMoving, meanFixed;
00128 Eigen::Matrix3d CMoving, CFixed, CSum, Cinv, R;
00129 NDTCell *cell;
00130 bool exists = false;
00131 double det = 0;
00132 for (unsigned int j = 0; j < _corr.size(); j++)
00133 {
00134 if (!_goodCorr[j])
00135 continue;
00136
00137 unsigned int i = _corr[j].second;
00138 if (i >= sourceNDT.size())
00139 {
00140 std::cout << "sourceNDT.size() : " << sourceNDT.size() << ", i: " << i << std::endl;
00141 }
00142 assert(i < sourceNDT.size());
00143
00144 meanMoving = sourceNDT[i]->getMean();
00145 CMoving= sourceNDT[i]->getCov();
00146
00147 this->computeDerivatives(meanMoving, CMoving, computeHessian);
00148
00149 point.x = meanMoving(0);
00150 point.y = meanMoving(1);
00151 point.z = meanMoving(2);
00152
00153 cell = targetNDT.getCellIdx(_corr[j].first);
00154 if(cell == NULL)
00155 {
00156 continue;
00157 }
00158 if(cell->hasGaussian_)
00159 {
00160 transformed = meanMoving - cell->getMean();
00161 CFixed = cell->getCov();
00162 CSum = (CFixed+CMoving);
00163 CSum.computeInverseAndDetWithCheck(Cinv,det,exists);
00164 if(!exists)
00165 {
00166
00167 continue;
00168 }
00169 double l = (transformed).dot(Cinv*(transformed));
00170 if(l*0 != 0)
00171 {
00172
00173 continue;
00174 }
00175 double sh = -lfd1*(exp(-lfd2*l/2));
00176
00177
00178
00179 if(!this->update_gradient_hessian(score_gradient,Hessian,transformed, Cinv, sh, computeHessian))
00180 {
00181 continue;
00182 }
00183 score_here += sh;
00184 cell = NULL;
00185 }
00186 }
00187 gettimeofday(&tv_end,NULL);
00188
00189
00190
00191 return score_here;
00192
00193 }
00194
00195 }