g2o
Loading...
Searching...
No Matches
optimize_sphere_by_sim3.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 <Eigen/Core>
28#include <Eigen/StdVector>
29#include <cmath>
30#include <fstream>
31#include <iostream>
32#include <vector>
33
35#include "g2o/core/factory.h"
39#include "g2o/core/solver.h"
47
48using namespace std;
49using namespace g2o;
50
52
53// Convert SE3 Vertex to Sim3 Vertex
54void ToVertexSim3(const g2o::VertexSE3& v_se3,
55 g2o::VertexSim3Expmap* const v_sim3) {
56 Eigen::Isometry3d se3 = v_se3.estimate().inverse();
57 Eigen::Matrix3d r = se3.rotation();
58 Eigen::Vector3d t = se3.translation();
59 g2o::Sim3 sim3(r, t, 1.0);
60
61 v_sim3->setEstimate(sim3);
62}
63
64// Convert Sim3 Vertex to SE3 Vertex
66 g2o::VertexSE3* const v_se3) {
67 g2o::Sim3 sim3 = v_sim3.estimate().inverse();
68 Eigen::Matrix3d r = sim3.rotation().toRotationMatrix();
69 Eigen::Vector3d t = sim3.translation();
70 Eigen::Isometry3d se3;
71 se3 = r;
72 se3.translation() = t;
73
74 v_se3->setEstimate(se3);
75}
76
77// Converte EdgeSE3 to EdgeSim3
78void ToEdgeSim3(const g2o::EdgeSE3& e_se3, g2o::EdgeSim3* const e_sim3) {
79 Eigen::Isometry3d se3 = e_se3.measurement().inverse();
80 Eigen::Matrix3d r = se3.rotation();
81 Eigen::Vector3d t = se3.translation();
82 g2o::Sim3 sim3(r, t, 1.0);
83
84 e_sim3->setMeasurement(sim3);
85}
86
87// Using VertexSim3 and EdgeSim3 is the core of this example.
88// This example optimize the data created by create_sphere.
89// Because the data is recore by VertexSE3 and EdgeSE3, SE3 is used for
90// interface and Sim is used for optimization.
91// g2o_viewer is available to the result.
92
93int main(int argc, char** argv) {
95 if (argc != 2) {
96 cout << "Usage: pose_graph_g2o_SE3 sphere.g2o" << endl;
97 return 1;
98 }
99 ifstream fin(argv[1]);
100 if (!fin) {
101 cout << "file " << argv[1] << " does not exist." << endl;
102 return 1;
103 }
104
105 // define the optimizer
106 typedef g2o::BlockSolver<g2o::BlockSolverTraits<7, 7>> BlockSolverType;
108 LinearSolverType;
109 auto solver = new g2o::OptimizationAlgorithmLevenberg(
110 std::make_unique<BlockSolverType>(std::make_unique<LinearSolverType>()));
111
112 g2o::SparseOptimizer optimizer;
113 optimizer.setAlgorithm(solver);
114 optimizer.setVerbose(true);
115
116 // Load and Save in SE3
117 g2o::SparseOptimizer interface;
118 interface.load(argv[1]);
119
120 // Convert all vertices
121 for (auto& tmp : interface.vertices()) {
122 const int& id = tmp.first;
123 g2o::VertexSE3* v_se3 = static_cast<g2o::VertexSE3*>(tmp.second);
125 v_sim3->setId(id);
126 v_sim3->setMarginalized(false);
127
128 ToVertexSim3(*v_se3, v_sim3);
129 optimizer.addVertex(v_sim3);
130 if (id == 0) {
131 v_sim3->setFixed(true);
132 }
133 }
134
135 // Convert all edges
136 int edge_index = 0;
137 for (auto& tmp : interface.edges()) {
138 g2o::EdgeSE3* e_se3 = static_cast<g2o::EdgeSE3*>(tmp);
139 int idx0 = e_se3->vertex(0)->id();
140 int idx1 = e_se3->vertex(1)->id();
141 g2o::EdgeSim3* e_sim3 = new g2o::EdgeSim3();
142
143 ToEdgeSim3(*e_se3, e_sim3);
144 e_sim3->setId(edge_index++);
145 e_sim3->setVertex(0, optimizer.vertices()[idx0]);
146 e_sim3->setVertex(1, optimizer.vertices()[idx1]);
147 e_sim3->information() = Eigen::Matrix<double, 7, 7>::Identity();
148
149 optimizer.addEdge(e_sim3);
150 }
151
152 cout << "optimizing ..." << endl;
153 optimizer.initializeOptimization();
154 optimizer.optimize(30);
155
156 cout << "saving optimization results in VertexSE3..." << endl;
157 auto vertices_sim3 = optimizer.vertices();
158 auto vertices_se3 = interface.vertices();
159
160 for (auto& tmp : vertices_sim3) {
161 const int& id = tmp.first;
162 g2o::VertexSim3Expmap* v_sim3 =
163 static_cast<g2o::VertexSim3Expmap*>(tmp.second);
164 g2o::VertexSE3* v_se3 = static_cast<g2o::VertexSE3*>(vertices_se3[id]);
165
166 ToVertexSE3(*v_sim3, v_se3);
167 }
168
169 interface.save("result.g2o");
170 return 0;
171}
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
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()
Implementation of a solver operating on the blocks of the Hessian.
Edge between two 3D pose vertices.
Definition edge_se3.h:44
7D edge between two Vertex7
void setVertex(size_t i, Vertex *v)
const Vertex * vertex(size_t i) const
int id() const
returns the id
const EdgeSet & edges() const
const VertexIDMap & vertices() const
linear solver which uses the sparse Cholesky solver from Eigen
void setFixed(bool fixed)
true => this node should be considered fixed during the optimization
void setMarginalized(bool marginalized)
true => this node should be marginalized out during the optimization
Implementation of the Levenberg Algorithm.
int optimize(int iterations, bool online=false)
void setVerbose(bool verbose)
virtual bool initializeOptimization(HyperGraph::EdgeSet &eset)
void setAlgorithm(OptimizationAlgorithm *algorithm)
3D pose Vertex, represented as an Isometry3
Definition vertex_se3.h:50
Sim3 Vertex, (x,y,z,qw,qx,qy,qz) the parameterization for the increments constructed is a 7d vector (...
#define G2O_FACTORY_EXPORT
Definition factory.h:143
int main()
Definition gicp_demo.cpp:44
Definition jet.h:876
void ToVertexSim3(const g2o::VertexSE3 &v_se3, g2o::VertexSim3Expmap *const v_sim3)
void ToEdgeSim3(const g2o::EdgeSE3 &e_se3, g2o::EdgeSim3 *const e_sim3)
void G2O_FACTORY_EXPORT g2o_type_VertexSE3(void)
void ToVertexSE3(const g2o::VertexSim3Expmap &v_sim3, g2o::VertexSE3 *const v_se3)
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)
const Quaternion & rotation() const
Definition sim3.h:249
Sim3 inverse() const
Definition sim3.h:200
const Vector3 & translation() const
Definition sim3.h:245