/* * 2DGridder implementation * * Copyright (C) Uwe Hebbelmann, Sebastian Stock, Andre Schemschat * * Released under the GPL version 3. * */ #include "grid/scanGrid.h" #include "grid/scanToGrid.h" #include "slam6d/scan.h" #include "grid/scanmanager.h" #include "grid/parcelmanager.h" #include "grid/gridWriter.h" #include "grid/viewpointinfo.h" #include "grid/gridlines.h" #include "slam6d/globals.icc" #include "grid/Debug.h" #include #include #include #include #include #include using std::cerr; using std::flush; #ifdef _MSC_VER #define _USE_MATH_DEFINES #include #include "GL/glut.h" /* Header File For The glu toolkit */ #include "XGetopt.h" #else #include #include #endif /** * 2DGridder * * Main class to convert a 3D scan to a 2D grid * * @author Andre Schemschadt, Uwe Hebbelmann, Sebastian Stock * @date 20.02.2008 */ /** * Explains the usage of this program's command line parameters * * @param prog name of the program */ void usage(char* prog) { #ifndef _MSC_VER const string bold("\033[1m"); const string normal("\033[m"); #else const string bold(""); const string normal(""); #endif cout << endl << "Usage: " << prog << endl << " [-s NR] [-e NR] [-m NR] [-M NR] [-f F] [-o DIR] [-t] " << endl << " [-h NR] [-H NR] [-r NR] [-w] [-p NR] [-P Nr] [-y] [-n] " < cannot be smaller than .\n"; exit(1); } break; case 'c': count = atoi(optarg); if( count < 1){ cerr << "Error: must be greater than 1.\n"; exit(1); } break; case 'R': resume = true; break; case 'm': maxDist = atoi(optarg); break; case 'M': minDist = atoi(optarg); break; case 't': readInitial = true; break; case 'f': try { type = formatname_to_io_type(optarg); } catch (...) { // runtime_error cerr << "Format " << optarg << " unknown." << endl; abort(); } break; case 'H': maxHeight = atoi(optarg); break; case 'h': minHeight = atoi(optarg); break; case 'g': writeGrids = true; break; case 'r': resolution = atol(optarg); if (resolution < 1) { cerr << "Error: cannot be smaller than 1.\n"; exit(1); } break; case 'w': waypoints = false; break; case 'n': neighbours = false; break; case 'p': parcelWidth = atol(optarg); if (parcelWidth < 1) { cerr << "Error: cannot be smaller than 1.\n"; exit(1); } break; case 'P': parcelHeight = atol(optarg); if (parcelHeight < 1) { cerr << "Error: cannot be smaller than 1.\n"; exit(1); } break; case 'y': correctY = true; break; case 'a': spotradius = atoi(optarg); if (spotradius < 0) { cerr << "Error: cannot be smaller than 0.\n"; exit(1); } break; case 'd': writeWorld = false; break; case 'l': writeLines = true; break; case 'i': writeWorldppm = true; break; case '?': usage(argv[0]); return 1; default: abort(); }} if (optind != argc-1) { cerr << "\n*** Input directory missing ***" << endl; usage(argv[0]); } inputdir = argv[optind]; //If no output directory is set, set it to the input directory if (outputdir == "") outputdir = inputdir; #ifndef _MSC_VER if (inputdir[inputdir.length()-1] != '/') inputdir = inputdir + "/"; if (outputdir[outputdir.length()-1] != '/') outputdir = outputdir + "/"; #else if (inputdir[inputdir.length()-1] != '\\') inputdir = inputdir + "\\"; if (outputdir[outputdir.length()-1] != '\\') outputdir = outputdir + "\\"; #endif return 0; } /** * Main function. * Reads the scan (scan000.3d, ...) and frames files (scan000.frames, ...) from the data directory. * The frames are used for animation of the matching process. Converts the 3D scan data to a 2D grid map * and stores it * * @param argc count of the command-line arguments * @param argv command-line arguments */ int main(int argc, char **argv){ // Start message cout << "(c) University of Osnabrueck, 2006 - 2008" << endl << endl << "Restricted Usage" << endl << "Don't use without permission" << endl; // Usage if(argc <= 1){ usage(argv[0]); } /////////////////////////////////////// // Defaultvalues string scandir = ""; string outputdir = "./parcels/"; int start = 0; int end = -1; int maxDistance = 2500; int minDistance = -1; bool readInitial = false; IOType scantype = UOS; bool correctY = false; double maxRelevantHeight = 50; double minRelevantHeight = 2; long resolution = 10; bool createWaypoints = true; bool createNeighbours = true; int parcelWidth = 1000; int parcelHeight = 1000; int spotradius = 15; bool writeWorld = true; bool writeLines = false; bool writeGrids = false; bool writeWorldppm = false; double isSolidPoint = 0.2; int count = 50; bool resume = false; /////////////////////////////////////// // parses the command-line arguments and sets the respective flags parseArgs(argc, argv, scandir, outputdir, start, end, maxDistance, minDistance, readInitial, scantype, correctY, minRelevantHeight, maxRelevantHeight, resolution, createWaypoints, createNeighbours, parcelWidth, parcelHeight, writeWorld, writeLines, writeGrids, spotradius, writeWorldppm, count, resume); // calculate parcel width and height parcelWidth /= resolution; parcelHeight /= resolution; // create parcelmanager cout << "Create parcelmanager ..." << endl; parcelmanager parcelman(parcelWidth, parcelHeight, outputdir, resolution, resume); cout << "Create viewpointlist ... " << endl; viewpointinfo viewpoint(outputdir); for (int i = start; i <= end; i+=count) { int endloop = i + count - 1 < end ? i + count - 1 : end; // get Scans cout << "Reading scans " << i << " to " << endloop << " ... "; scanmanager scanman; scanman.startscan(scandir, outputdir, scantype, i, endloop, readInitial, maxDistance, minDistance, correctY); cout << "Done."<< endl; // create grid from scans cout << "Creating grids " << i << " to " << endloop << " ... "; scanToGrid stg(resolution, minRelevantHeight, maxRelevantHeight, maxDistance, spotradius, createWaypoints, createNeighbours); cout << "Done."<< endl; // convert scans cout << "Converting " << scanman.getScanCount() <<" scans ... "; vector grids; for(size_t j = 0; j < scanman.getScanCount(); j++) { cout << "." << flush; double* p = scanman.getMatrix(j).back(); scanman.getScan(j).transformAll(p); grids.push_back(stg.convert(scanman.getScan(j), p)); } cout << "Done." << endl; // start writing cout << "Processing from " << i << " to " << endloop << endl; for(size_t j = 0; j < grids.size(); ++j) { cout << "Adding scan " << i << " ... " << flush; parcelman.addGrid(grids[j], grids[j]->getViewpointX(), grids[j]->getViewpointZ()); viewpoint.addGrid(grids[j]); cout << "Done."<< endl; } // print grids for each scan if wished if(writeGrids) { cout << "Writing grids " << i << " to " << endloop << " ... " << endl; string str; stringstream stream; for(size_t j = 0; j < grids.size(); ++j) { cout << "Writing grid " << i << " ... " << flush; stream.clear(); stream << outputdir << "grid" << j+i << ".ppm "; stream >> str; ppmWriter writer(str); writer.write(*grids[j]); cout << "Done."<