eval_octree_accuracy.cpp
Go to the documentation of this file.
00001 /*
00002  * OctoMap - An Efficient Probabilistic 3D Mapping Framework Based on Octrees
00003  * http://octomap.github.com/
00004  *
00005  * Copyright (c) 2009-2013, K.M. Wurm and A. Hornung, University of Freiburg
00006  * All rights reserved.
00007  * License: New BSD
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions are met:
00011  *
00012  *     * Redistributions of source code must retain the above copyright
00013  *       notice, this list of conditions and the following disclaimer.
00014  *     * Redistributions in binary form must reproduce the above copyright
00015  *       notice, this list of conditions and the following disclaimer in the
00016  *       documentation and/or other materials provided with the distribution.
00017  *     * Neither the name of the University of Freiburg nor the names of its
00018  *       contributors may be used to endorse or promote products derived from
00019  *       this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031  * POSSIBILITY OF SUCH DAMAGE.
00032  */
00033 
00034 #include <string.h>
00035 #include <stdlib.h>
00036 #include <iostream>
00037 #include <fstream>
00038 
00039 #include <octomap/octomap.h>
00040 #include <octomap/octomap_timing.h>
00041 
00042 using namespace std;
00043 using namespace octomap;
00044 
00045 void printUsage(char* self){
00046   std::cerr << "USAGE: " << self << " <InputFile.graph>\n";
00047   std::cerr << "This tool is part of OctoMap and evaluates the statistical accuracy\n"
00048                "of an octree map from scan graph data (point clouds with poses).\n";
00049 
00050   std::cerr << "OPTIONS:\n"
00051             "  -res <resolution> (default: 0.1 m)\n"
00052             "  -m <maxrange> (optional) \n"
00053             "  -n <max scan no.> (optional) \n"
00054   "\n";
00055 
00056   exit(0);
00057 }
00058 
00059 
00060 int main(int argc, char** argv) {
00061   // default values:
00062   double res = 0.1;
00063 
00064   if (argc < 2)
00065     printUsage(argv[0]);
00066 
00067   string graphFilename = std::string(argv[1]);
00068 
00069   double maxrange = -1;
00070   int max_scan_no = -1;
00071   int skip_scan_eval = 5;
00072 
00073   int arg = 1;
00074   while (++arg < argc) {
00075     if (! strcmp(argv[arg], "-i"))
00076       graphFilename = std::string(argv[++arg]);
00077     else if (! strcmp(argv[arg], "-res"))
00078       res = atof(argv[++arg]);
00079     else if (! strcmp(argv[arg], "-m"))
00080       maxrange = atof(argv[++arg]);
00081     else if (! strcmp(argv[arg], "-n"))
00082       max_scan_no = atoi(argv[++arg]);
00083     else {
00084       printUsage(argv[0]);
00085     }
00086   }
00087 
00088   cout << "\nReading Graph file\n===========================\n";
00089   ScanGraph* graph = new ScanGraph();
00090   if (!graph->readBinary(graphFilename))
00091     exit(2);
00092   
00093   unsigned int num_points_in_graph = 0;
00094   if (max_scan_no > 0) {
00095     num_points_in_graph = graph->getNumPoints(max_scan_no-1);
00096     cout << "\n Data points in graph up to scan " << max_scan_no << ": " << num_points_in_graph << endl;
00097   }
00098   else {
00099     num_points_in_graph = graph->getNumPoints();
00100     cout << "\n Data points in graph: " << num_points_in_graph << endl;
00101   }
00102 
00103   cout << "\nCreating tree\n===========================\n";
00104   OcTree* tree = new OcTree(res);
00105 
00106   unsigned int numScans = graph->size();
00107   unsigned int currentScan = 1;
00108   for (ScanGraph::iterator scan_it = graph->begin(); scan_it != graph->end(); scan_it++) {
00109 
00110     if (currentScan % skip_scan_eval != 0){
00111       if (max_scan_no > 0) cout << "("<<currentScan << "/" << max_scan_no << ") " << flush;
00112       else cout << "("<<currentScan << "/" << numScans << ") " << flush;
00113       tree->insertPointCloud(**scan_it, maxrange);
00114     } else
00115       cout << "(SKIP) " << flush;
00116 
00117     if ((max_scan_no > 0) && (currentScan == (unsigned int) max_scan_no))
00118       break;
00119 
00120     currentScan++;
00121   }
00122 
00123   tree->expand();
00124 
00125   
00126   cout << "\nEvaluating scans\n===========================\n";
00127   currentScan = 1;
00128   unsigned num_points = 0;
00129   unsigned num_voxels_correct = 0;
00130   unsigned num_voxels_wrong = 0;
00131   unsigned num_voxels_unknown = 0;
00132 
00133 
00134   for (ScanGraph::iterator scan_it = graph->begin(); scan_it != graph->end(); scan_it++) {
00135 
00136     if (currentScan % skip_scan_eval == 0){
00137       if (max_scan_no > 0) cout << "("<<currentScan << "/" << max_scan_no << ") " << flush;
00138       else cout << "("<<currentScan << "/" << numScans << ") " << flush;
00139 
00140 
00141       pose6d frame_origin = (*scan_it)->pose;
00142       point3d sensor_origin = frame_origin.inv().transform((*scan_it)->pose.trans());
00143 
00144       // transform pointcloud:
00145       Pointcloud scan (*(*scan_it)->scan);
00146       scan.transform(frame_origin);
00147       point3d origin = frame_origin.transform(sensor_origin);
00148 
00149       KeySet free_cells, occupied_cells;
00150       tree->computeUpdate(scan, origin, free_cells, occupied_cells, maxrange);
00151 
00152       num_points += scan.size();
00153 
00154       // count free cells
00155       for (KeySet::iterator it = free_cells.begin(); it != free_cells.end(); ++it) {
00156         OcTreeNode* n = tree->search(*it);
00157         if (n){
00158           if (tree->isNodeOccupied(n))
00159             num_voxels_wrong++;
00160           else
00161             num_voxels_correct++;
00162         } else
00163           num_voxels_unknown++;
00164       } // count occupied cells
00165       for (KeySet::iterator it = occupied_cells.begin(); it != occupied_cells.end(); ++it) {
00166         OcTreeNode* n = tree->search(*it);
00167         if (n){
00168           if (tree->isNodeOccupied(n))
00169             num_voxels_correct++;
00170           else
00171             num_voxels_wrong++;
00172         } else
00173           num_voxels_unknown++;
00174       }
00175 
00176 
00177     }
00178 
00179     if ((max_scan_no > 0) && (currentScan == (unsigned int) max_scan_no))
00180       break;
00181 
00182     currentScan++;
00183 
00184 
00185   }
00186 
00187   cout << "\nFinished evaluating " << num_points <<"/"<< num_points_in_graph << " points.\n"
00188       <<"Voxels correct: "<<num_voxels_correct<<" #wrong: " <<num_voxels_wrong << " #unknown: " <<num_voxels_unknown
00189       <<". % correct: "<< num_voxels_correct/double(num_voxels_correct+num_voxels_wrong)<<"\n\n";
00190 
00191 
00192   delete graph;
00193   delete tree;
00194   
00195   return 0;
00196 }


octomap
Author(s): Kai M. Wurm , Armin Hornung
autogenerated on Thu Feb 11 2016 23:50:59