/* * graphToro implementation * * Copyright (C) Jochen Sprickerhof * * Released under the GPL version 3. * */ /** * @file TORO wrapper * @author Jochen Sprickerhof. Institute of Computer Science, University of Osnabrueck, Germany. */ #include "slam6d/graphToro.h" #include "slam6d/metaScan.h" #include "slam6d/lum6Deuler.h" #include "slam6d/globals.icc" #include using std::ofstream; using std::ifstream; #include #include using namespace NEWMAT; /** * This function is used to match a set of laser scans with any minimally * connected Graph. * * @param gr Some Graph with no real subgraphs except for itself * @param allScans Contains all laser scans * @param nrIt The number of iterations the LUM-algorithm will run * @return Euclidian distance of all pose shifts */ double graphToro::doGraphSlam6D(Graph gr, vector allScans, int nrIt) { Matrix C(6, 6); double invers[16], rela[16], rPos[3], rPosTheta[3], rPosQuat[4]; double Pl0[16]; ofstream outFile("toro.graph"); int n = gr.getNrScans(); for(int i = 0; i < n; i++) { QuatRPYEuler(allScans[i]->get_rPosQuat(), rPosTheta); outFile << "VERTEX3" << " " << i << " " << (allScans[i]->get_rPos()[0]/100) << " " << (allScans[i]->get_rPos()[1]/100) << " " << (allScans[i]->get_rPos()[2]/100) << " " << rPosTheta[0] << " " << rPosTheta[1] << " " << rPosTheta[2] << endl; } for(int i = 0; i < gr.getNrLinks(); i++){ int first = gr.getLink(i,0); int last = gr.getLink(i,1); if(first != last-1) { vector meta_start; for(int i = first - 2; i <= first + 2; i++) { if(i >= 0) { meta_start.push_back(allScans[i]); } } MetaScan *start = new MetaScan(meta_start, false, false); //static size of metascan int offset_last_start = 2; int offset_last_end = 0; vector meta_end; for(int i = last - offset_last_start; i <= last + offset_last_end && i < n; i++) { if(i >= 0) { meta_end.push_back(allScans[i]); } } MetaScan *end = new MetaScan(meta_end, false, false); memcpy(Pl0, allScans[last]->get_transMat(), 16 * sizeof(double)); my_icp->match(start, end); delete start; delete end; } M4inv(allScans[last]->get_transMat(), invers); MMult(invers, allScans[first]->get_transMat(), rela); Matrix4ToQuat(rela, rPosQuat, rPos); QuatRPYEuler(rPosQuat, rPosTheta); lum6DEuler::covarianceEuler(allScans[first], allScans[last], my_icp->get_nns_method(), my_icp->get_rnd(), my_icp->get_max_dist_match2(), &C); outFile << "EDGE3" << " " << last << " " << first << " " << (rPos[0]/100) << " " << (rPos[1]/100) << " " << (rPos[2]/100) << " " << rPosTheta[0] << " " << rPosTheta[1] << " " << rPosTheta[2] << " "; for(int i = 1; i < 7; i++) for(int j = i; j < 7; j++) outFile << C(i, j) << " "; outFile << endl; if(first != last-1) { allScans[last]->transformToMatrix(Pl0,Scan::INVALID); } } outFile.close(); system("sort toro.graph > toro2.graph && mv toro2.graph toro.graph && ./bin/toro3d toro.graph"); ifstream inFile("toro-treeopt-final.graph"); string tag; int id; double dd; double rPosN[3], rPosThetaN[3]; while(inFile) { inFile >> tag; if(tag == "VERTEX3") { inFile >> id; if(id == n-1) { inFile >> rPosN[0] >> rPosN[1] >> rPosN[2] >> rPosThetaN[0] >> rPosThetaN[1] >> rPosThetaN[2]; rPosN[0] *= 100; rPosN[1] *= 100; rPosN[2] *= 100; } else { inFile >> rPos[0] >> rPos[1] >> rPos[2] >> rPosTheta[0] >> rPosTheta[1] >> rPosTheta[2]; rPos[0] *= 100; rPos[1] *= 100; rPos[2] *= 100; RPYEulerQuat(rPosTheta, rPosQuat); if(id != 0) { allScans[id]->transformToQuat(rPos, rPosQuat, Scan::GRAPHTORO, 1); } } } else if(tag == "EDGE3") { inFile >> id >> id; for(int i=0; i < 22; i++) { inFile >> dd; } } } RPYEulerQuat(rPosThetaN, rPosQuat); allScans[n-1]->transformToQuat(rPosN, rPosQuat, Scan::GRAPHTORO, 2); inFile.close(); return DBL_MAX; }