/* Copyright 2011. All rights reserved. Institute of Measurement and Control Systems Karlsruhe Institute of Technology, Germany Authors: Andreas Geiger libicp is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or any later version. libicp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with libicp; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "icp.h" using namespace std; Icp::Icp (double *M,const int32_t M_num,const int32_t dimension) : dim(dimension), sub_step(10), max_iter(200), T_num(0),iterations(0),min_delta(1e-6), current_delta(1), euclidean_fitness(1e14), hasConvergedBool(false), checkEventTime(false), giveOutputIfNotConvergedB(false),instantForce(false) { // check for correct dimensionality if (dimension!=2 && dimension!=3) { cout << "ERROR: LIBICP works only for data of dimensionality 2 or 3" << endl; M_tree = 0; return; } // check for minimum number of points if (M_num<5) { cout << "ERROR: LIBICP works only with at least 5 model points" << endl; M_tree = 0; return; } // excldue kdTree generation as long as we are fitting non-iteratively /* // copy model points to M_data M_data.resize(boost::extents[M_num][dimension]); for (int32_t m=0; m active; this->T_num = T_number; //we don't need a model if fitInstant is called if(instantForce){ active.clear(); for (int32_t i=0; i &active) { // check if we have at least 5 active points if (active.size()<5) return false; // iterate until convergence for (int32_t iter=0; iter 1){ // cout << "false convergence, event id drift is too large!" << endl; // hasConvergedBool = false; // return false; // } // } hasConvergedBool=true; iterations = iter+1; return true; } } if(giveOutputIfNotConvergedB){ hasConvergedBool = true; return true; } cout << "WARNING: icp did not converge in " << max_iter << " iterations!" << endl; hasConvergedBool=false; return false; } double Icp::computeFitnessRMSE(const double *T, const Matrix &R,const Matrix &t){ //fitness has either not been computed or is unrealistically small (i.e. for identical data sets) //if(euclidean_fitness < 1e-18) // return 0; if(T_num == 0){ cout << "no points in template/model!" << endl; return 1e14; } if(!hasConvergedBool){ return 1e14; } if(dim==2){ // extract matrix and translation vector double r00 = R.val[0][0]; double r01 = R.val[0][1]; double r10 = R.val[1][0]; double r11 = R.val[1][1]; double t0 = t.val[0][0]; double t1 = t.val[1][0]; double x0=0,y0=0,x1=0,y1=0,d=0,s=0; for(int32_t idx=0; idx