g2o
Loading...
Searching...
No Matches
edge_se2_lotsofxy.cpp
Go to the documentation of this file.
1// g2o - General Graph Optimization
2// Copyright (C) 2011 R. Kuemmerle, G. Grisetti, H. Strasdat, 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 "edge_se2_lotsofxy.h"
28
29#include <cassert>
30
31#ifdef G2O_HAVE_OPENGL
34#endif
35
36namespace g2o {
37
39 : BaseVariableSizedEdge<-1, VectorX>(), _observedPoints(0) {
40 resize(0);
41}
42
44 VertexSE2* pose = static_cast<VertexSE2*>(_vertices[0]);
45
46 for (unsigned int i = 0; i < _observedPoints; i++) {
47 VertexPointXY* xy = static_cast<VertexPointXY*>(_vertices[1 + i]);
48 Vector2 m = pose->estimate().inverse() * xy->estimate();
49
50 unsigned int index = 2 * i;
51 _error[index] = m[0] - _measurement[index];
52 _error[index + 1] = m[1] - _measurement[index + 1];
53 }
54}
55
56bool EdgeSE2LotsOfXY::read(std::istream& is) {
57 is >> _observedPoints;
59
60 // read the measurements
61 for (unsigned int i = 0; i < _observedPoints; i++) {
62 unsigned int index = 2 * i;
63 is >> _measurement[index] >> _measurement[index + 1];
64 }
65
66 // read the information matrix
67 for (unsigned int i = 0; i < _observedPoints * 2; i++) {
68 // fill the "upper triangle" part of the matrix
69 for (unsigned int j = i; j < _observedPoints * 2; j++) {
70 is >> information()(i, j);
71 }
72
73 // fill the lower triangle part
74 for (unsigned int j = 0; j < i; j++) {
75 information()(i, j) = information()(j, i);
76 }
77 }
78
79 return true;
80}
81
82bool EdgeSE2LotsOfXY::write(std::ostream& os) const {
83 // write number of observed points
84 os << "|| " << _observedPoints;
85
86 // write measurements
87 for (unsigned int i = 0; i < _observedPoints; i++) {
88 unsigned int index = 2 * i;
89 os << " " << _measurement[index] << " " << _measurement[index + 1];
90 }
91
92 // write information matrix
93 for (unsigned int i = 0; i < _observedPoints * 2; i++) {
94 for (unsigned int j = i; j < _observedPoints * 2; j++) {
95 os << " " << information()(i, j);
96 }
97 }
98
99 return os.good();
100}
101
103 const VertexSE2* vi = static_cast<const VertexSE2*>(_vertices[0]);
104 const double& x1 = vi->estimate().translation()[0];
105 const double& y1 = vi->estimate().translation()[1];
106 const double& th1 = vi->estimate().rotation().angle();
107
108 double ct = std::cos(th1);
109 double st = std::sin(th1);
110
111 MatrixX Ji;
112 unsigned int rows = 2 * (_vertices.size() - 1);
113 Ji.resize(rows, 3);
114 Ji.fill(0);
115
116 Matrix2 poseRot; // inverse of the rotation matrix associated to the pose
117 poseRot << ct, st, -st, ct;
118
119 Matrix2 minusPoseRot = -poseRot;
120
121 for (unsigned int i = 1; i < _vertices.size(); i++) {
123
124 const double& x2 = point->estimate()[0];
125 const double& y2 = point->estimate()[1];
126
127 unsigned int index = 2 * (i - 1);
128
129 Ji.block<2, 2>(index, 0) = minusPoseRot;
130
131 Ji(index, 2) = ct * (y2 - y1) + st * (x1 - x2);
132 Ji(index + 1, 2) = st * (y1 - y2) + ct * (x1 - x2);
133
134 MatrixX Jj;
135 Jj.resize(rows, 2);
136 Jj.fill(0);
137 Jj.block<2, 2>(index, 0) = poseRot;
138
139 _jacobianOplus[i] = Jj;
140 }
141 _jacobianOplus[0] = Ji;
142}
143
145 OptimizableGraph::Vertex* toEstimate) {
146 (void)toEstimate;
147
148 assert(initialEstimatePossible(fixed, toEstimate) &&
149 "Bad vertices specified");
150
151 VertexSE2* pose = static_cast<VertexSE2*>(_vertices[0]);
152
153#ifdef _MSC_VER
154 std::vector<bool> estimate_this(_observedPoints, true);
155#else
156 bool estimate_this[_observedPoints];
157 for (unsigned int i = 0; i < _observedPoints; i++) {
158 estimate_this[i] = true;
159 }
160#endif
161
162 for (std::set<HyperGraph::Vertex*>::iterator it = fixed.begin();
163 it != fixed.end(); ++it) {
164 for (unsigned int i = 1; i < _vertices.size(); i++) {
165 VertexPointXY* vert = static_cast<VertexPointXY*>(_vertices[i]);
166 if (vert->id() == (*it)->id()) estimate_this[i - 1] = false;
167 }
168 }
169
170 for (unsigned int i = 1; i < _vertices.size(); i++) {
171 if (estimate_this[i - 1]) {
172 unsigned int index = 2 * (i - 1);
173 Vector2 submeas(_measurement[index], _measurement[index + 1]);
174 VertexPointXY* vert = static_cast<VertexPointXY*>(_vertices[i]);
175 vert->setEstimate(pose->estimate() * submeas);
176 }
177 }
178}
179
181 const OptimizableGraph::VertexSet& fixed,
182 OptimizableGraph::Vertex* toEstimate) {
183 (void)toEstimate;
184
185 for (std::set<HyperGraph::Vertex*>::iterator it = fixed.begin();
186 it != fixed.end(); ++it) {
187 if (_vertices[0]->id() == (*it)->id()) {
188 return 1.0;
189 }
190 }
191
192 return -1.0;
193}
194
196 VertexSE2* pose = static_cast<VertexSE2*>(_vertices[0]);
197
198 for (unsigned int i = 0; i < _observedPoints; i++) {
199 VertexPointXY* xy = static_cast<VertexPointXY*>(_vertices[1 + i]);
200 Vector2 m = pose->estimate().inverse() * xy->estimate();
201
202 unsigned int index = 2 * i;
203 _measurement[index] = m[0];
204 _measurement[index + 1] = m[1];
205 }
206
207 return true;
208}
209
210} // end namespace g2o
EIGEN_STRONG_INLINE const InformationType & information() const
information matrix of the constraint
Definition base_edge.h:107
Measurement _measurement
the measurement of the edge
Definition base_edge.h:146
ErrorVector _error
Definition base_edge.h:149
base class to represent an edge connecting an arbitrary number of nodes
std::vector< JacobianType > _jacobianOplus
jacobians of the edge (w.r.t. oplus)
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()
virtual void initialEstimate(const OptimizableGraph::VertexSet &, OptimizableGraph::Vertex *)
virtual double initialEstimatePossible(const OptimizableGraph::VertexSet &, OptimizableGraph::Vertex *)
void setSize(int vertices)
virtual bool write(std::ostream &os) const
write the vertex to a stream
virtual bool read(std::istream &is)
read the vertex from a stream, i.e., the internal state of the vertex
virtual bool setMeasurementFromState()
VertexContainer _vertices
int id() const
returns the id
std::set< Vertex * > VertexSet
A general case Vertex for optimization.
const Vector2 & translation() const
translational component
Definition se2.h:57
SE2 inverse() const
invert :-)
Definition se2.h:83
const Rotation2D & rotation() const
rotational component
Definition se2.h:61
2D pose Vertex, (x,y,theta)
Definition vertex_se2.h:41
MatrixN< Eigen::Dynamic > MatrixX
Definition eigen_types.h:74
MatrixN< 2 > Matrix2
Definition eigen_types.h:71
VectorN< 2 > Vector2
Definition eigen_types.h:50
VectorN< Eigen::Dynamic > VectorX
Definition eigen_types.h:55