#include using namespace std; #include "slam6d/cuda/icp6Dcuda.h" #include "slam6d/cuda/CIcpGpuCuda.cuh" #include "newmat/newmat.h" void icp6Dcuda::initGPUicp(float max_rad, float min_rad, int iter, int max_iter, int max_proctime, float max_dev, const double trans[], const double trans_inv[]) { #ifndef WITH_SCANSERVER unsigned int max_size = Scan::max_points_red_size; #else //WITH_SCANSERVER unsigned int max_size = Scan::getMaxCountReduced(); #endif //WITH_SCANSERVER if (max_scnSize < max_size) { if (icp != 0) { delete icp; icp = 0; } } if (icp == 0) { max_scnSize = max_size; icp = new CIcpGpuCuda((unsigned)10, ceil((float)max_size/10.f) , (unsigned)max_num_iterations); icp->setMaxProcTime((double) max_proctime); icp->setMaxDeviation((double) max_dev); icp->setSearchRadius((float) max_rad, (float) min_rad, (unsigned)max_num_iterations); } } icp6Dcuda::icp6Dcuda(icp6Dminimizer *my_icp6Dminimizer, double max_dist_match, int max_num_iterations, bool quiet, bool meta, int rnd, bool eP, int anim, double epsilonICP, int nns_method, bool cuda_enabled) : icp6D(my_icp6Dminimizer, max_dist_match, max_num_iterations, quiet, meta, rnd, eP, anim, epsilonICP, nns_method, cuda_enabled) { icp = 0; max_scnSize = 0; } /** * Matches a 3D Scan against a 3D Scan * @param PreviousScan The scan or metascan forming the model * @param CurrentScan The current scan thas is to be matched * @return The number of iterations done in this matching run */ int icp6Dcuda::match(Scan* PreviousScan, Scan* CurrentScan) { #ifndef WITH_SCANSERVER int mdlSize = PreviousScan->get_points_red_size(), scnSize = CurrentScan->get_points_red_size(); #else //WITH_SCANSERVER int mdlSize = PreviousScan->getCountReduced(), scnSize = CurrentScan->getCountReduced(); #endif //WITH_SCANSERVER double** mdl; float** scn; const double *trans; double trans_inv[16]; trans = PreviousScan->get_transMat(); M4inv(trans, trans_inv); initGPUicp(sqrt(max_dist_match2), sqrt(max_dist_match2), max_num_iterations, max_num_iterations, INT_MAX, epsilonICP, trans, trans_inv); h_idata = icp->getModelPointer(); fHstScn = icp->getScenePointer(); icp->setTrans_Trans_inv(trans, trans_inv); icp->setSize(10, ceil((float)max(mdlSize, scnSize)/10.0f)); #ifndef WITH_SCANSERVER double **mod_dat = PreviousScan->get_org_points_red(); double *const*scn_dat = CurrentScan->get_points_red(); #else //WITH_SCANSERVER DataXYZ scn_dat(CurrentScan->getXYZReduced()); DataXYZ mod_dat(PreviousScan->getXYZReducedOriginal()); #endif //WITH_SCANSERVER mdl = h_idata; scn = fHstScn; cout << "model point cloud size is " << mdlSize << "\n"; for (unsigned int i = 0; i < mdlSize; ++i) { mdl[i][0] = (float)mod_dat[i][0]; mdl[i][1] = (float)mod_dat[i][1]; mdl[i][2] = (float)mod_dat[i][2]; } cout << "scene point cloud size is " << scnSize << "\n"; for (unsigned int i = 0; i < scnSize; ++i) { scn[0][i] = (float)scn_dat[i][0]; scn[1][i] = (float)scn_dat[i][1]; scn[2][i] = (float)scn_dat[i][2]; } icp->setTreePointer(const_cast(PreviousScan->getANNTree())); float result[4][4]; // doICP icp->setPointClouds(); icp->iteration(); Matrix* M = icp->getMatrix(); for (int i = 0 ; i < 4 ; ++i){ for(int j = 0 ; j < 4 ; ++j) { result[i][j] = (*M)(i+1,j+1); } } if(anim > 0){ Matrix** mats = icp->getMatrices(); for(int ci = 0 ; ci < max_num_iterations ; ci += anim){ Matrix* cur_mat = mats[ci]; double xf[16]; for(int i = 1; i < 5 ; ++i) for(int j = 1; j < 5; ++j) xf[(i-1)+(j-1)*4] = (*cur_mat)(i,j); CurrentScan->transform(xf, Scan::ICP, 0); } } else { double alignxf[16]; for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j){ alignxf[i + j * 4] = result[i][j]; } CurrentScan->transform(alignxf, Scan::ICP, 0); // write end pose } return EXIT_SUCCESS; }