g2o
Loading...
Searching...
No Matches
base_fixed_sized_edge.h
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#ifndef G2O_BASE_FIXED_SIZED_EDGE_H
28#define G2O_BASE_FIXED_SIZED_EDGE_H
29
30#include <array>
31#include <iostream>
32#include <limits>
33#include <utility>
34
35#include "base_edge.h"
37#include "g2o/config.h"
38#include "g2o/stuff/misc.h"
40#include "robust_kernel.h"
41
42namespace g2o {
43
44namespace internal {
45
46// creating a bool array
47template <int K>
48std::array<bool, K> createBoolArray() {
49 std::array<bool, K> aux = {false};
50 return aux;
51}
52template <>
53inline std::array<bool, 0> createBoolArray<0>() {
54 return std::array<bool, 0>();
55}
56
57// assumes i < j
58// duplication of internal::computeUpperTriangleIndex in
59// g2o/core/base_variable_sized_edge.hpp
60constexpr int pair_to_index(const int i, const int j) {
61 return j * (j - 1) / 2 + i;
62}
63
70 constexpr TrivialPair(int f, int s) : first(f), second(s) {}
71 bool operator==(const TrivialPair& other) const {
72 return first == other.first && second == other.second;
73 }
74};
75
86constexpr TrivialPair index_to_pair(const int k, const int j = 0) {
87 return k < j ? TrivialPair{k, j} : index_to_pair(k - j, j + 1);
88}
89
91template <typename T>
93 // if the size is known at compile time, we have to call the c'tor of
94 // Eigen::Map with corresponding values
95 constexpr int r =
96 T::RowsAtCompileTime == Eigen::Dynamic ? 0 : T::RowsAtCompileTime;
97 constexpr int c =
98 T::ColsAtCompileTime == Eigen::Dynamic ? 0 : T::ColsAtCompileTime;
99 return T(nullptr, r, c);
100}
102template <typename... Args>
103std::tuple<Args...> createHessianMaps(const std::tuple<Args...>&) {
104 return std::tuple<Args...>{createHessianMapK<Args>()...};
105}
106
107template <int I, typename EdgeType, typename... CtorArgs>
108typename std::enable_if<I == -1, OptimizableGraph::Vertex*>::type
109createNthVertexType(int /*i*/, const EdgeType& /*t*/, CtorArgs... /*args*/) {
110 return nullptr;
111}
112
113template <int I, typename EdgeType, typename... CtorArgs>
114typename std::enable_if<I != -1, OptimizableGraph::Vertex*>::type
115createNthVertexType(int i, const EdgeType& t, CtorArgs... args) {
116 if (i == I) {
117 using VertexType = typename EdgeType::template VertexXnType<I>;
118 return new VertexType(args...);
119 }
120 return createNthVertexType<I - 1, EdgeType, CtorArgs...>(i, t, args...);
121}
122} // namespace internal
123
124template <int D, typename E, typename... VertexTypes>
125class BaseFixedSizedEdge : public BaseEdge<D, E> {
126 public:
127 template <int N, typename... Types>
128 using NthType = typename std::tuple_element<N, std::tuple<Types...>>::type;
130 template <int VertexN>
131 using VertexXnType = NthType<VertexN, VertexTypes...>;
133 template <int VertexN>
134 static constexpr int VertexDimension() {
136 };
142 // clang-format off
143 template <int VertexN>
144 constexpr typename std::enable_if<VertexXnType<VertexN>::Dimension != -1, int>::type vertexDimension() const {
146 };
147 template <int VertexN>
148 typename std::enable_if<VertexXnType<VertexN>::Dimension == -1, int>::type vertexDimension() const {
149 return vertexXn<VertexN>()->dimension();
150 };
151 // clang-format on
155 template <int VertexN>
157 return static_cast<const VertexXnType<VertexN>*>(_vertices[VertexN]);
158 }
159 template <int VertexN>
161 return static_cast<VertexXnType<VertexN>*>(_vertices[VertexN]);
162 }
163
168
169 template <int EdgeDimension, int VertexDimension>
170 using JacobianType = typename Eigen::Matrix<
171 double, EdgeDimension, VertexDimension,
172 EdgeDimension == 1 ? Eigen::RowMajor : Eigen::ColMajor>::AlignedMapType;
173
175 template <int DN, int DM>
176 using HessianBlockType = Eigen::Map<
177 Eigen::Matrix<double, DN, DM,
178 DN == 1 ? Eigen::RowMajor : Eigen::ColMajor>,
179 Eigen::Matrix<double, DN, DM,
180 DN == 1 ? Eigen::RowMajor : Eigen::ColMajor>::Flags &
181 Eigen::PacketAccessBit
182 ? Eigen::Aligned
183 : Eigen::Unaligned>;
184 template <int K>
188 template <int K>
192 template <typename>
194 template <std::size_t... Ints>
195 struct HessianTupleType<std::index_sequence<Ints...>> {
196 using type = std::tuple<HessianBlockTypeK<Ints>...>;
197 using typeTransposed = std::tuple<HessianBlockTypeKTransposed<Ints>...>;
198 };
199 static const std::size_t _nr_of_vertices = sizeof...(VertexTypes);
200 static const std::size_t _nr_of_vertex_pairs =
203 std::make_index_sequence<_nr_of_vertex_pairs>>::type;
205 std::make_index_sequence<_nr_of_vertex_pairs>>::typeTransposed;
206 using HessianRowMajorStorage = std::array<bool, _nr_of_vertex_pairs>;
207
209 : BaseEdge<D, E>(),
210 _hessianRowMajor(internal::createBoolArray<_nr_of_vertex_pairs>()),
211 _hessianTuple(internal::createHessianMaps(_hessianTuple)),
213 internal::createHessianMaps(_hessianTupleTransposed)),
214 _jacobianOplus({nullptr, D, VertexTypes::Dimension}...) {
216 }
217
219 template <typename... CtorArgs>
220 OptimizableGraph::Vertex* createVertex(int i, CtorArgs... args) {
221 if (i < 0) return nullptr;
223 sizeof...(VertexTypes) - 1,
224 typename std::remove_reference<decltype(*this)>::type, CtorArgs...>(
225 i, *this, args...);
226 };
227
228 virtual void resize(size_t size);
229
230 template <std::size_t... Ints>
231 bool allVerticesFixedNs(std::index_sequence<Ints...>) const;
232 virtual bool allVerticesFixed() const;
233
234 virtual void linearizeOplus(JacobianWorkspace& jacobianWorkspace);
235 template <std::size_t... Ints>
237 std::index_sequence<Ints...>);
238
243 virtual void linearizeOplus();
244 template <std::size_t... Ints>
245 void linearizeOplusNs(std::index_sequence<Ints...>);
246 template <int N>
248
251 template <int N>
252 const typename std::tuple_element<
253 N, std::tuple<JacobianType<D, VertexTypes::Dimension>...>>::type&
255 return std::get<N>(_jacobianOplus);
256 }
259 template <int N>
260 typename std::tuple_element<
261 N, std::tuple<JacobianType<D, VertexTypes::Dimension>...>>::type&
263 return std::get<N>(_jacobianOplus);
264 }
265
270 virtual void constructQuadraticForm();
271 template <std::size_t... Ints>
273 const ErrorVector& weightedError,
274 std::index_sequence<Ints...>);
275 template <int N>
277 const ErrorVector& weightedError);
278
279 template <int N, typename AtOType>
281 std::index_sequence<>);
282
283 template <int N, std::size_t... Ints, typename AtOType>
284 void constructOffDiagonalQuadraticFormMs(const AtOType& AtO,
285 std::index_sequence<Ints...>);
286 template <int N, int M, typename AtOType>
287 void constructOffDiagonalQuadraticFormM(const AtOType& AtO);
288
289 virtual void mapHessianMemory(double* d, int i, int j, bool rowMajor);
290
291 using BaseEdge<D, E>::resize;
292 using BaseEdge<D, E>::computeError;
293
294 protected:
295 using BaseEdge<D, E>::_measurement;
296 using BaseEdge<D, E>::_information;
297 using BaseEdge<D, E>::_error;
298 using BaseEdge<D, E>::_vertices;
299 using BaseEdge<D, E>::_dimension;
300
304 std::tuple<JacobianType<D, VertexTypes::Dimension>...> _jacobianOplus;
305
306 public:
307 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
308};
309
311
312} // end namespace g2o
313
314#endif
InformationType _information
Definition base_edge.h:147
internal::BaseEdgeTraits< D >::ErrorVector ErrorVector
Definition base_edge.h:90
internal::BaseEdgeTraits< D >::InformationType InformationType
Definition base_edge.h:91
Measurement _measurement
the measurement of the edge
Definition base_edge.h:146
ErrorVector _error
Definition base_edge.h:149
HessianBlockType< VertexXnType< internal::index_to_pair(K).first >::Dimension, VertexXnType< internal::index_to_pair(K).second >::Dimension > HessianBlockTypeK
BaseEdge< D, E >::InformationType InformationType
virtual bool allVerticesFixed() const
bool allVerticesFixedNs(std::index_sequence< Ints... >) const
void constructOffDiagonalQuadraticFormMs(const AtOType &AtO, std::index_sequence< Ints... >)
std::enable_if< VertexXnType< VertexN >::Dimension==-1, int >::type vertexDimension() const
static const std::size_t _nr_of_vertex_pairs
virtual void mapHessianMemory(double *d, int i, int j, bool rowMajor)
BaseEdge< D, E >::ErrorVector ErrorVector
std::tuple_element< N, std::tuple< JacobianType< D, VertexTypes::Dimension >... > >::type & jacobianOplusXn()
typename HessianTupleType< std::make_index_sequence< _nr_of_vertex_pairs > >::type HessianTuple
static const std::size_t _nr_of_vertices
void linearizeOplusNs(std::index_sequence< Ints... >)
void constructOffDiagonalQuadraticFormMs(const AtOType &, std::index_sequence<>)
static constexpr int VertexDimension()
Size of the N-th vertex at compile time.
typename HessianTupleType< std::make_index_sequence< _nr_of_vertex_pairs > >::typeTransposed HessianTupleTransposed
Eigen::Map< Eigen::Matrix< double, DN, DM, DN==1 ? Eigen::RowMajor :Eigen::ColMajor >, Eigen::Matrix< double, DN, DM, DN==1 ? Eigen::RowMajor :Eigen::ColMajor >::Flags &Eigen::PacketAccessBit ? Eigen::Aligned :Eigen::Unaligned > HessianBlockType
it requires quite some ugly code to get the type of hessians...
std::array< bool, _nr_of_vertex_pairs > HessianRowMajorStorage
HessianTupleTransposed _hessianTupleTransposed
void linearizeOplus_allocate(JacobianWorkspace &jacobianWorkspace, std::index_sequence< Ints... >)
VertexXnType< VertexN > * vertexXn()
void constructQuadraticFormN(const InformationType &omega, const ErrorVector &weightedError)
HessianRowMajorStorage _hessianRowMajor
constexpr std::enable_if< VertexXnType< VertexN >::Dimension!=-1, int >::type vertexDimension() const
std::tuple< JacobianType< D, VertexTypes::Dimension >... > _jacobianOplus
typename Eigen::Matrix< double, EdgeDimension, VertexDimension, EdgeDimension==1 ? Eigen::RowMajor :Eigen::ColMajor >::AlignedMapType JacobianType
BaseEdge< D, E >::Measurement Measurement
const std::tuple_element< N, std::tuple< JacobianType< D, VertexTypes::Dimension >... > >::type & jacobianOplusXn() const
typename std::tuple_element< N, std::tuple< Types... > >::type NthType
virtual void resize(size_t size)
void constructOffDiagonalQuadraticFormM(const AtOType &AtO)
HessianBlockType< VertexXnType< internal::index_to_pair(K).second >::Dimension, VertexXnType< internal::index_to_pair(K).first >::Dimension > HessianBlockTypeKTransposed
NthType< VertexN, VertexTypes... > VertexXnType
The type of the N-th vertex.
void constructQuadraticFormNs(const InformationType &omega, const ErrorVector &weightedError, std::index_sequence< Ints... >)
OptimizableGraph::Vertex * createVertex(int i, CtorArgs... args)
create an instance of the Nth VertexType
const VertexXnType< VertexN > * vertexXn() const
VertexContainer _vertices
virtual void resize(size_t size)
provide memory workspace for computing the Jacobians
virtual void computeError()=0
A general case Vertex for optimization.
some general case utility functions
constexpr TrivialPair index_to_pair(const int k, const int j=0)
std::array< bool, K > createBoolArray()
T createHessianMapK()
helper function to call the c'tor of Eigen::Map
std::tuple< Args... > createHessianMaps(const std::tuple< Args... > &)
helper function for creating a tuple of Eigen::Map
std::array< bool, 0 > createBoolArray< 0 >()
std::enable_if< I==-1, OptimizableGraph::Vertex * >::type createNthVertexType(int, const EdgeType &, CtorArgs...)
constexpr int pair_to_index(const int i, const int j)
Definition jet.h:876
constexpr TrivialPair(int f, int s)
bool operator==(const TrivialPair &other) const