Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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
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
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
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 }
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 }