88 {
89 string inputFilename;
90 string loadLookup;
91 bool listTypes;
92 int updateGraphEachN = 10;
93 string dummy;
94
96 arg.
param(
"update", updateGraphEachN, 10,
97 "updates after x odometry nodes, (default: 10)");
98 arg.
param(
"listTypes", listTypes,
false,
"list the registered types");
99 arg.
param(
"renameTypes", loadLookup,
"",
100 "create a lookup for loading types into other types,\n\t "
101 "TAG_IN_FILE=INTERNAL_TAG_FOR_TYPE,TAG2=INTERNAL2\n\t e.g., "
102 "VERTEX_CAM=VERTEX_SE3:EXPMAP");
104 "graph file which will be processed", true);
105
107
108 if (listTypes) {
110 }
111
113
114
115 if (loadLookup.size() > 0) {
117 }
118 if (inputFilename.size() == 0) {
119 cerr << "No input data specified" << endl;
120 return 0;
121 } else if (inputFilename == "-") {
122 cerr << "Read input from stdin" << endl;
123 if (!optimizer.
load(cin)) {
124 cerr << "Error loading graph" << endl;
125 return 2;
126 }
127 } else {
128 cerr << "Read input from " << inputFilename << endl;
129 ifstream ifs(inputFilename.c_str());
130 if (!ifs) {
131 cerr << "Failed to open file" << endl;
132 return 1;
133 }
134 if (!optimizer.
load(ifs)) {
135 cerr << "Error loading graph" << endl;
136 return 2;
137 }
138 }
139 cerr <<
"Loaded " << optimizer.
vertices().size() <<
" vertices" << endl;
140 cerr <<
"Loaded " << optimizer.
edges().size() <<
" edges" << endl;
141
142 if (optimizer.
vertices().size() == 0) {
143 cerr << "Graph contains no vertices" << endl;
144 return 1;
145 }
146
147 if (1) {
148 int maxDim = 0;
149
150 cerr << "# incremental settings" << endl;
151 cerr << "#\t solve every " << updateGraphEachN << endl;
152
153 SparseOptimizer::VertexIDMap vertices = optimizer.
vertices();
154 for (SparseOptimizer::VertexIDMap::const_iterator it = vertices.begin();
155 it != vertices.end(); ++it) {
156 const SparseOptimizer::Vertex* v =
157 static_cast<const SparseOptimizer::Vertex*>(it->second);
158 maxDim = (max)(maxDim, v->dimension());
159 }
160
161 vector<SparseOptimizer::Edge*> edges;
162 for (SparseOptimizer::EdgeSet::iterator it = optimizer.
edges().begin();
163 it != optimizer.
edges().end(); ++it) {
164 SparseOptimizer::Edge* e = dynamic_cast<SparseOptimizer::Edge*>(*it);
165 edges.push_back(e);
166 }
167 optimizer.
edges().clear();
170
171
173
174 int vertexCount = 0;
175 int lastOptimizedVertexCount = 0;
176 bool addNextEdge = true;
177 bool freshlyOptimized = false;
179 int maxInGraph = -1;
180 for (vector<SparseOptimizer::Edge*>::iterator it = edges.begin();
181 it != edges.end(); ++it) {
182 SparseOptimizer::Edge* e = *it;
183 bool optimize = false;
184
185 if (addNextEdge && !optimizer.
vertices().empty()) {
186 int idMax = (max)(e->vertices()[0]->id(), e->vertices()[1]->id());
187 if (maxInGraph < idMax && !freshlyOptimized) {
188 addNextEdge = false;
189 optimize = true;
190 } else {
191 addNextEdge = true;
192 optimize = false;
193 }
194 }
195
196 SparseOptimizer::Vertex* v1 = optimizer.
vertex(e->vertices()[0]->id());
197 SparseOptimizer::Vertex* v2 = optimizer.
vertex(e->vertices()[1]->id());
198 if (!v1 && addNextEdge) {
199
200 SparseOptimizer::Vertex* v =
201 dynamic_cast<SparseOptimizer::Vertex*>(e->vertices()[0]);
203 maxInGraph = (max)(maxInGraph, v->id());
204
205 assert(v1Added);
206 if (!v1Added)
207 cerr << "Error adding vertex " << v->id() << endl;
208 else
209 verticesAdded.insert(v);
210 if (v->dimension() == maxDim) vertexCount++;
211
212 if (v->dimension() == 3) {
213 cout << "ADD VERTEX_XYT " << v->id() << ";" << endl;
214 } else if (v->dimension() == 6) {
215 cout << "ADD VERTEX_XYZRPY " << v->id() << ";" << endl;
216 }
217 }
218
219 if (!v2 && addNextEdge) {
220 SparseOptimizer::Vertex* v =
221 dynamic_cast<SparseOptimizer::Vertex*>(e->vertices()[1]);
222
224 maxInGraph = (max)(maxInGraph, v->id());
225
226 assert(v2Added);
227 if (!v2Added)
228 cerr << "Error adding vertex " << v->id() << endl;
229 else
230 verticesAdded.insert(v);
231 if (v->dimension() == maxDim) vertexCount++;
232
233 if (v->dimension() == 3) {
234 cout << "ADD VERTEX_XYT " << v->id() << ";" << endl;
235 } else if (v->dimension() == 6) {
236 cout << "ADD VERTEX_XYZRPY " << v->id() << ";" << endl;
237 }
238 }
239
240 if (addNextEdge) {
241 if (e->dimension() == 3) {
242 static int edgeCnt = 0;
243 double* information = e->informationData();
244 double meas[3];
245 e->getMeasurementData(meas);
246
247 cout << "ADD EDGE_XYT " << edgeCnt++ << " " << e->vertices()[0]->id()
248 << " " << e->vertices()[1]->id() << " " << meas[0] << " "
249 << meas[1] << " " << meas[2];
250 for (int i = 0; i < 3; ++i)
251 for (int j = i; j < 3; ++j) cout << " " << information[i * 3 + j];
252 cout << ";" << endl;
253 } else if (e->dimension() == 6) {
254
255 cerr << "NOT IMPLEMENTED YET" << endl;
256 }
257 static bool firstEdge = true;
258 if (firstEdge) {
259 firstEdge = false;
260 cout << "FIX 0;" << endl;
261 }
262
263
264
266 cerr << "Unable to add edge " << e->vertices()[0]->id() << " -> "
267 << e->vertices()[1]->id() << endl;
268 }
269 }
270
271 freshlyOptimized = false;
272 if (optimize) {
273
274 if (vertexCount - lastOptimizedVertexCount >= updateGraphEachN) {
275 cout << "SOLVE_STATE;" << endl;
276 cout << "QUERY_STATE;" << endl;
277 lastOptimizedVertexCount = vertexCount;
278 }
279
280 addNextEdge = true;
281 freshlyOptimized = true;
282 --it;
283 }
284
285 }
286 }
287
288 return 0;
289}
Command line parsing of argc and argv.
bool parseArgs(int argc, char **argv, bool exitOnError=true)
void paramLeftOver(const std::string &name, std::string &p, const std::string &defValue, const std::string &desc, bool optional=false)
void param(const std::string &name, bool &p, bool defValue, const std::string &desc)
void printRegisteredTypes(std::ostream &os, bool comment=false) const
static Factory * instance()
return the instance
std::set< Vertex * > VertexSet
const EdgeSet & edges() const
const VertexIDMap & vertices() const
void setVerbose(bool verbose)
Sort Edges for inserting them sequentially.
virtual bool addEdge(HyperGraph::Edge *e)
virtual bool addVertex(HyperGraph::Vertex *v, Data *userData)
virtual bool load(std::istream &is)
Vertex * vertex(int id)
returns the vertex number id appropriately casted
void setRenamedTypesFromString(const std::string &types)