g2o
Loading...
Searching...
No Matches
convertSegmentLine.cpp
Go to the documentation of this file.
1// g2o - General Graph Optimization
2// Copyright (C) 2011 R. Kuemmerle, G. Grisetti, W. Burgard
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright notice,
10// this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27#include <algorithm>
28#include <cassert>
29#include <csignal>
30#include <fstream>
31#include <iomanip>
32#include <iostream>
33#include <sstream>
34#include <string>
35
39#include "g2o/core/factory.h"
49#include "g2o/stuff/macros.h"
51#include "g2o/stuff/timeutil.h"
53
54using namespace std;
55using namespace g2o;
56using namespace Eigen;
57
70
71typedef std::map<int, LineInfo> LineInfoMap;
72
73int main(int argc, char** argv) {
74 string outputfilename;
75 string inputFilename;
76 CommandArgs arg;
77 arg.param("o", outputfilename, "", "output final version of the graph");
78 arg.paramLeftOver("graph-input", inputFilename, "",
79 "graph file which will be processed", true);
80
81 arg.parseArgs(argc, argv);
82 OptimizableGraph inGraph;
83
84 // registering all the types from the libraries
85
86 if (inputFilename.size() == 0) {
87 cerr << "No input data specified" << endl;
88 return 0;
89 } else if (inputFilename == "-") {
90 cerr << "Read input from stdin" << endl;
91 if (!inGraph.load(cin)) {
92 cerr << "Error loading graph" << endl;
93 return 2;
94 }
95 } else {
96 cerr << "Read input from " << inputFilename << endl;
97 ifstream ifs(inputFilename.c_str());
98 if (!ifs) {
99 cerr << "Failed to open file" << endl;
100 return 1;
101 }
102 if (!inGraph.load(ifs)) {
103 cerr << "Error loading graph" << endl;
104 return 2;
105 }
106 }
107 cerr << "Loaded " << inGraph.vertices().size() << " vertices" << endl;
108 cerr << "Loaded " << inGraph.edges().size() << " edges" << endl;
109
110 cerr << "filling in linfoMap and odoms" << endl;
111 LineInfoMap lmap;
112 OptimizableGraph outGraph;
113 // insert all lines in the infomap
114 int currentId = -1000;
115 bool firstVertexFound = false;
116 for (OptimizableGraph::VertexIDMap::iterator it = inGraph.vertices().begin();
117 it != inGraph.vertices().end(); ++it) {
118 currentId = currentId > it->first ? currentId : it->first;
119
120 VertexSE2* pose = dynamic_cast<VertexSE2*>(it->second);
121 if (pose) {
122 VertexSE2* npose = new VertexSE2();
123 npose->setEstimate(pose->estimate());
124 npose->setId(pose->id());
125 outGraph.addVertex(npose);
126 if (!firstVertexFound) {
127 firstVertexFound = true;
128 npose->setFixed(true);
129 }
130 }
131
132 VertexSegment2D* s = dynamic_cast<VertexSegment2D*>(it->second);
133 if (s) {
134 LineInfo linfo(s);
135 outGraph.addVertex(linfo.line);
136 lmap.insert(make_pair(s->id(), linfo));
137 }
138 }
139
140 currentId++;
141
142 cerr << "filling in edges and odoms" << endl;
143 for (OptimizableGraph::EdgeSet::iterator it = inGraph.edges().begin();
144 it != inGraph.edges().end(); ++it) {
145 EdgeSE2* ods = dynamic_cast<EdgeSE2*>(*it);
146 if (ods) {
147 EdgeSE2* ods2 = new EdgeSE2();
148 ods2->setMeasurement(ods->measurement());
149 ods2->setInformation(ods->information());
150 ods2->vertices()[0] = outGraph.vertex(ods->vertices()[0]->id());
151 ods2->vertices()[1] = outGraph.vertex(ods->vertices()[1]->id());
152 outGraph.addEdge(ods2);
153 }
154
155 EdgeSE2Segment2D* es = dynamic_cast<EdgeSE2Segment2D*>(*it);
156 EdgeSE2Segment2DLine* el = dynamic_cast<EdgeSE2Segment2DLine*>(*it);
158 dynamic_cast<EdgeSE2Segment2DPointLine*>(*it);
159
160 if (es || el || espl) {
161 VertexSE2* pose = dynamic_cast<VertexSE2*>((*it)->vertices()[0]);
162 VertexSegment2D* segment =
163 dynamic_cast<VertexSegment2D*>((*it)->vertices()[1]);
164 if (!pose) continue;
165 pose = dynamic_cast<VertexSE2*>(outGraph.vertex(pose->id()));
166 LineInfoMap::iterator lit = lmap.find(segment->id());
167 assert(lit != lmap.end());
168 LineInfo& linfo = lit->second;
169 VertexLine2D* line = linfo.line;
170 VertexPointXY*& p1 = linfo.p1;
171 VertexPointXY*& p2 = linfo.p2;
172
173 EdgeSE2Line2D* el2 = new EdgeSE2Line2D();
174 el2->vertices()[0] = pose;
175 el2->vertices()[1] = line;
176 if (el) {
177 el2->setMeasurement(el->measurement());
178 el2->setInformation(el->information());
179 outGraph.addEdge(el2);
180 }
181 if (es) {
182 el2->setMeasurement(
184 Matrix2d el2info;
185 el2info << 10000, 0, 0, 1000;
186 el2->setInformation(el2info);
187 outGraph.addEdge(el2);
188 Matrix4d si = es->information();
189 if (!p1) {
190 p1 = new VertexPointXY();
191 p1->setEstimate(segment->estimateP1());
192 p1->setId(currentId++);
193 outGraph.addVertex(p1);
194 line->p1Id = p1->id();
195
197 p1e->vertices()[0] = line;
198 p1e->vertices()[1] = p1;
199 p1e->setMeasurement(0);
200 Eigen::Matrix<double, 1, 1> p1i;
201 p1i(0, 0) = 1e6;
202 p1e->setInformation(p1i);
203 outGraph.addEdge(p1e);
204 }
205 if (!p2) {
206 p2 = new VertexPointXY();
207 p2->setEstimate(segment->estimateP2());
208 p2->setId(currentId++);
209 outGraph.addVertex(p2);
210 line->p2Id = p2->id();
211
213 p2e->vertices()[0] = line;
214 p2e->vertices()[1] = p2;
215 p2e->setMeasurement(0);
216 Eigen::Matrix<double, 1, 1> p2i;
217 p2i(0, 0) = 1e6;
218 p2e->setInformation(p2i);
219 outGraph.addEdge(p2e);
220 }
221
222 EdgeSE2PointXY* p1e = new EdgeSE2PointXY();
223 p1e->vertices()[0] = pose;
224 p1e->vertices()[1] = p1;
225 p1e->setMeasurement(es->measurementP1());
226 Matrix2d p1i = si.block<2, 2>(0, 0);
227 p1e->setInformation(p1i);
228 outGraph.addEdge(p1e);
229
230 EdgeSE2PointXY* p2e = new EdgeSE2PointXY();
231 p2e->vertices()[0] = pose;
232 p2e->vertices()[1] = p2;
233 p2e->setMeasurement(es->measurementP2());
234 Matrix2d p2i = si.block<2, 2>(2, 2);
235 p2e->setInformation(p2i);
236 outGraph.addEdge(p2e);
237 }
238
239 if (espl) {
240 Matrix3d si = espl->information();
241 Vector2d lparams;
242 lparams[0] = espl->theta();
243 Vector2d n(cos(espl->theta()), sin(espl->theta()));
244 lparams[1] = n.dot(espl->point());
245 Matrix2d li;
246 li << si(2, 2), 0, 0, 1000;
247 el2->setMeasurement(lparams);
248 el2->setInformation(li);
249 outGraph.addEdge(el2);
250
251 VertexPointXY*& pX = (espl->pointNum() == 0) ? p1 : p2;
252 if (!pX) {
253 cerr << "mkp: " << line->id() << endl;
254 pX = new VertexPointXY();
255 pX->setId(currentId++);
256 outGraph.addVertex(pX);
257
258 Vector2d estPx;
259 if (espl->pointNum()) {
260 estPx = segment->estimateP1();
261 line->p1Id = pX->id();
262 } else {
263 estPx = segment->estimateP2();
264 line->p2Id = pX->id();
265 }
266 pX->setEstimate(estPx);
267
269 pXe->vertices()[0] = line;
270 pXe->vertices()[1] = pX;
271 pXe->setMeasurement(0);
272 Eigen::Matrix<double, 1, 1> pXi;
273 pXi(0, 0) = 1e6;
274 pXe->setInformation(pXi);
275 outGraph.addEdge(pXe);
276 }
277
278 EdgeSE2PointXY* pXe = new EdgeSE2PointXY();
279 pXe->vertices()[0] = pose;
280 pXe->vertices()[1] = pX;
281 pXe->setMeasurement(espl->point());
282 Matrix2d pXi = si.block<2, 2>(0, 0);
283 pXe->setInformation(pXi);
284 outGraph.addEdge(pXe);
285 }
286 }
287 }
288
289 if (outputfilename.size() > 0) {
290 if (outputfilename == "-") {
291 cerr << "saving to stdout";
292 outGraph.save(cout);
293 } else {
294 cerr << "saving " << outputfilename << " ... ";
295 outGraph.save(outputfilename.c_str());
296 }
297 cerr << "done." << endl;
298 }
299
300 // destroy all the singletons
301 // Factory::destroy();
302 // OptimizationAlgorithmFactory::destroy();
303 // HyperGraphActionLibrary::destroy();
304
305 return 0;
306}
EIGEN_STRONG_INLINE const Measurement & measurement() const
accessor functions for the measurement represented by the edge
Definition base_edge.h:119
virtual void setMeasurement(const Measurement &m)
Definition base_edge.h:122
EIGEN_STRONG_INLINE const InformationType & information() const
information matrix of the constraint
Definition base_edge.h:107
void setInformation(const InformationType &information)
Definition base_edge.h:111
const EstimateType & estimate() const
return the current estimate of the vertex
void setEstimate(const EstimateType &et)
set the estimate for the vertex also calls updateCache()
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)
G2O_TYPES_SLAM2D_ADDONS_API Vector2 measurementP2()
G2O_TYPES_SLAM2D_ADDONS_API Vector2 measurementP1()
2D edge between two Vertex2
Definition edge_se2.h:41
virtual void setMeasurement(const SE2 &m)
Definition edge_se2.h:56
const VertexContainer & vertices() const
int id() const
returns the id
const EdgeSet & edges() const
const VertexIDMap & vertices() const
void setFixed(bool fixed)
true => this node should be considered fixed during the optimization
2D pose Vertex, (x,y,theta)
Definition vertex_se2.h:41
Vector2 estimateP1() const
Vector2 estimateP2() const
std::map< int, LineInfo > LineInfoMap
int main()
Definition gicp_demo.cpp:44
Definition jet.h:938
Eigen::Vector2d computeLineParameters(const Eigen::Vector2d &p1, const Eigen::Vector2d &p2)
Definition simutils.cpp:148
Definition jet.h:876
LineInfo(VertexSegment2D *s)
VertexPointXY * p2
VertexLine2D * line
VertexPointXY * p1
virtual bool addEdge(HyperGraph::Edge *e)
virtual bool save(std::ostream &os, int level=0) const
save the graph to a stream. Again uses the Factory system.
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
utility functions for handling time related stuff