g2o
Loading...
Searching...
No Matches
g2o_incremental.cpp
Go to the documentation of this file.
1// g2o - General Graph Optimization
2// Copyright (C) 2011 R. Kuemmerle, G. Grisetti, W. Burgard
3//
4// g2o is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published
6// by the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// g2o is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17#include <cassert>
18#include <csignal>
19#include <iostream>
20
23#include "g2o/stuff/macros.h"
25#include "g2o/stuff/tictoc.h"
28
29static bool hasToStop = false;
30
31using namespace std;
32using namespace g2o;
33
38 int fromId;
39 int toId;
40 std::vector<double> measurement;
41 std::vector<double> information;
42};
43
48 bool operator()(const EdgeInformation& e1, const EdgeInformation& e2) {
49 int i11 = e1.fromId, i12 = e1.toId;
50 if (i11 > i12) swap(i11, i12);
51 int i21 = e2.fromId, i22 = e2.toId;
52 if (i21 > i22) swap(i21, i22);
53 if (i12 < i22) return true;
54 if (i12 > i22) return false;
55 return i11 < i21;
56 }
57};
58
59inline void solveAndPrint(G2oSlamInterface& slamInterface, bool verbose) {
60 G2oSlamInterface::SolveResult solverState = slamInterface.solve();
61 if (!verbose) {
62 switch (solverState) {
64 cout << "."; //<< flush;
65 break;
67 cout << "b " << slamInterface.optimizer()->vertices().size() << endl;
68 break;
69 default:
70 break;
71 }
72 }
73}
74
75void sigquit_handler(int sig) {
76 if (sig == SIGINT) {
77 hasToStop = 1;
78 static int cnt = 0;
79 if (cnt++ == 2) {
80 cerr << __PRETTY_FUNCTION__ << " forcing exit" << endl;
81 exit(1);
82 }
83 }
84}
85
86int main(int argc, char** argv) {
87 string inputFilename;
88 string outputFilename;
89 int updateEachN;
90 int batchEachN;
91 bool verbose;
92 bool vis;
93 // command line parsing
94 CommandArgs arg;
95 arg.param("batch", batchEachN, 100,
96 "solve by a batch Cholesky after inserting N nodes");
97 arg.param("update", updateEachN, 10,
98 "update the graph after inserting N nodes");
99 arg.param("v", verbose, false, "verbose output of the optimization process");
100 arg.param("g", vis, false, "gnuplot visualization");
101 arg.param("o", outputFilename, "", "output the final graph");
102 arg.param("i", inputFilename, "",
103 "input file (default g2o format), if not given read via stdin");
104
105 arg.parseArgs(argc, argv);
106
108 optimizer.setVerbose(verbose);
109 optimizer.setForceStopFlag(&hasToStop);
110 optimizer.vizWithGnuplot = vis;
111
112 G2oSlamInterface slamInterface(&optimizer);
113 slamInterface.setUpdateGraphEachN(updateEachN);
114 slamInterface.setBatchSolveEachN(batchEachN);
115
116 cerr << "Updating every " << updateEachN << endl;
117 cerr << "Batch step every " << batchEachN << endl;
118
119 if (inputFilename.size() > 0) { // operating on a file
120 vector<EdgeInformation> edgesFromGraph;
121
122 // HACK force tictoc statistics
123#if defined _MSC_VER || defined __MINGW32__
124 _putenv_s("G2O_ENABLE_TICTOC", "1");
125#else
126 setenv("G2O_ENABLE_TICTOC", "1", 1);
127#endif
128
129 // parse the edge from the file
130 int graphDimension = 0;
131 cerr << "Parsing " << inputFilename << " ... ";
132 tictoc("parsing");
133 ifstream ifs(inputFilename.c_str());
134 if (!ifs) {
135 cerr << "Failure to open " << inputFilename << endl;
136 return 1;
137 }
138 stringstream currentLine;
139 while (readLine(ifs, currentLine)) {
140 string token;
141 currentLine >> token;
142 if (token == "EDGE_SE2") {
143 graphDimension = 3;
144 edgesFromGraph.push_back(EdgeInformation());
145 EdgeInformation& currentEdge = edgesFromGraph.back();
146 currentLine >> currentEdge.fromId >> currentEdge.toId;
147 currentEdge.measurement.resize(3);
148 currentLine >> currentEdge.measurement[0] >>
149 currentEdge.measurement[1] >> currentEdge.measurement[2];
150 currentEdge.information.resize(6);
151 for (int i = 0; i < 6; ++i) currentLine >> currentEdge.information[i];
152 } else if (token == "EDGE_SE3:QUAT") {
153 graphDimension = 6;
154 edgesFromGraph.push_back(EdgeInformation());
155 EdgeInformation& currentEdge = edgesFromGraph.back();
156 currentLine >> currentEdge.fromId >> currentEdge.toId;
157 currentEdge.measurement.resize(7);
158 for (size_t i = 0; i < currentEdge.measurement.size(); ++i)
159 currentLine >> currentEdge.measurement[i];
160 currentEdge.information.resize(21);
161 for (size_t i = 0; i < currentEdge.information.size(); ++i)
162 currentLine >> currentEdge.information[i];
163 }
164 }
165 assert(graphDimension > 0);
166 sort(edgesFromGraph.begin(), edgesFromGraph.end(),
168 tictoc("parsing");
169 cerr << "done." << endl;
170
171 // adding edges to the graph. Add all edges connecting a node and then call
172 // optimize
173 tictoc("inc_optimize");
174 int lastNode = 2;
175 slamInterface.addNode("", 0, graphDimension, vector<double>());
176 for (vector<EdgeInformation>::const_iterator it = edgesFromGraph.begin();
177 it != edgesFromGraph.end(); ++it) {
178 const EdgeInformation& e = *it;
179 int minNodeId = max(e.fromId, e.toId);
180 if (minNodeId > lastNode) {
181 // cerr << "try to solve" << endl;
182 lastNode = minNodeId;
183 solveAndPrint(slamInterface, verbose);
184 }
185 // cerr << "adding " << e.fromId << " " << e.toId << endl;
186 slamInterface.addEdge("", 0, graphDimension, e.fromId, e.toId,
188 }
189 solveAndPrint(slamInterface, verbose);
190 tictoc("inc_optimize");
191 } else {
192 // Reading the protocol via stdin
193 SlamParser::ParserInterface parserInterface(&slamInterface);
194 while (parserInterface.parseCommand(cin)) {
195 }
196 }
197
198 if (outputFilename.size() > 0) {
199 cerr << "Saving " << outputFilename << endl;
200 optimizer.save(outputFilename.c_str());
201 }
202
203 return 0;
204}
top-level interface to the parser
bool parseCommand(std::istream &input)
Command line parsing of argc and argv.
bool parseArgs(int argc, char **argv, bool exitOnError=true)
void param(const std::string &name, bool &p, bool defValue, const std::string &desc)
SparseOptimizerOnline * optimizer()
bool addEdge(const std::string &tag, int id, int dimension, int v1, int v2, const std::vector< double > &measurement, const std::vector< double > &information)
bool addNode(const std::string &tag, int id, int dimension, const std::vector< double > &values)
const VertexIDMap & vertices() const
void setForceStopFlag(bool *flag)
void setVerbose(bool verbose)
SlamParser::Parser::token token
void sigquit_handler(int sig)
static bool hasToStop
void solveAndPrint(G2oSlamInterface &slamInterface, bool verbose)
int main()
Definition gicp_demo.cpp:44
#define __PRETTY_FUNCTION__
Definition macros.h:90
int readLine(std::istream &is, std::stringstream &currentLine)
double tictoc(const char *algorithmPart)
Profile the timing of certain parts of your algorithm.
Definition tictoc.cpp:118
Definition jet.h:876
Store the information parsed from a g2o file.
std::vector< double > measurement
std::vector< double > information
Sort Edges for inserting them sequentially.
Definition g2o.cpp:66
bool operator()(const EdgeInformation &e1, const EdgeInformation &e2)
virtual bool save(std::ostream &os, int level=0) const
save the graph to a stream. Again uses the Factory system.