g2o
Toggle main menu visibility
Loading...
Searching...
No Matches
g2o
core
auto_differentiation.h
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
#ifndef G2O_AUTO_DIFFERENTIATION_H
28
#define G2O_AUTO_DIFFERENTIATION_H
29
30
#include <algorithm>
31
#include <cassert>
32
#include <type_traits>
33
34
#include "
eigen_types.h
"
35
#include "
g2o/autodiff/autodiff.h
"
36
#include "
g2o/stuff/misc.h
"
37
#include "
g2o_core_api.h
"
38
39
namespace
g2o
{
40
45
template
<
typename
Edge>
46
struct
EstimateAccessor
{
47
template
<
int
k>
48
EIGEN_STRONG_INLINE
double
*
data
(Edge* that) {
49
return
const_cast<
double
*
>
(that->template vertexXn<k>()->estimate().data());
50
}
51
};
52
62
template
<
typename
Edge>
63
class
EstimateAccessorGet
{
64
public
:
65
template
<
int
k>
66
EIGEN_STRONG_INLINE
double
*
data
(Edge* that) {
67
auto
& buffer = std::get<k>(
_estimateBuffer
);
68
buffer.resize(that->template vertexDimension<k>());
69
double
* rawBuffer =
const_cast<
double
*
>
(buffer.data());
70
bool
gotData = that->template vertexXn<k>()->getEstimateData(rawBuffer);
71
assert(gotData &&
"Called getEstimateData, but seems unimplmented"
);
72
return
gotData ? rawBuffer :
nullptr
;
73
}
74
75
protected
:
76
template
<
typename
>
77
struct
BufferType
;
78
template
<std::size_t... Ints>
79
struct
BufferType
<
std
::index_sequence<Ints...>> {
80
using
type
=
81
std::tuple<VectorN<Edge::template VertexXnType<Ints>::Dimension>...>;
82
};
83
84
using
Buffer
=
typename
BufferType
<
85
std::make_index_sequence<Edge::_nr_of_vertices>>::type;
86
Buffer
_estimateBuffer
;
87
};
88
154
template
<
typename
Edge,
typename
EstimateAccess = EstimateAccessor<Edge>>
155
class
AutoDifferentiation
{
156
public
:
158
template
<
int
EdgeDimension,
int
VertexDimension>
159
using
ADJacobianType
=
160
typename
Eigen::Matrix<double, EdgeDimension, VertexDimension,
161
Eigen::RowMajor>;
162
164
static
void
computeError
(Edge* that) {
165
static_assert
(Edge::Dimension > 0,
166
"Dynamically sized edges are not supported"
);
167
computeErrorNs
(that, std::make_index_sequence<Edge::_nr_of_vertices>());
168
}
169
177
static
void
linearize
(Edge* that) {
178
static_assert
(Edge::Dimension > 0,
179
"Dynamically sized edges are not supported"
);
180
linearizeOplusNs
(that, std::make_index_sequence<Edge::_nr_of_vertices>());
181
}
182
183
protected
:
185
template
<std::size_t... Ints>
186
static
void
computeErrorNs
(Edge* that, std::index_sequence<Ints...>) {
187
static_assert
(
188
std::min({Edge::template VertexXnType<Ints>::Dimension...}) > 0,
189
"Dynamically sized vertices are not supported"
);
190
EstimateAccess estimateAccess;
191
(*that)(estimateAccess.template data<Ints>(that)..., that->errorData());
192
}
193
197
template
<std::size_t... Ints>
198
static
void
linearizeOplusNs
(Edge* that, std::index_sequence<Ints...>) {
199
static_assert
(
200
std::min({Edge::template VertexXnType<Ints>::Dimension...}) > 0,
201
"Dynamically sized vertices are not supported"
);
202
// all vertices are fixed, no need to compute anything here
203
if
(that->allVerticesFixed()) {
204
(void(that->template jacobianOplusXn<Ints>().setZero()), ...);
205
return
;
206
}
207
208
// tuple containing the Jacobians
209
std::tuple<
ADJacobianType
<Edge::Dimension,
210
Edge::template VertexXnType<Ints>::Dimension>...>
211
ad_jacobians;
212
213
// setting up the pointer to the parameters and the Jacobians for calling
214
// AD.
215
EstimateAccess estimateAccess;
216
double
* parameters[] = {estimateAccess.template data<Ints>(that)...};
217
// double* parameters[] = { /* trivial case would be */
218
// const_cast<double*>(that->template
219
// vertexXn<Ints>()->estimate().data())...};
220
221
// pointers to the Jacobians, set to NULL if vertex is fixed to skip
222
// computation
223
double
* jacobians[] = {
224
that->template vertexXn<Ints>()->fixed()
225
? nullptr
226
:
const_cast<
double
*
>
(std::get<Ints>(ad_jacobians).data())...};
227
// Calls the automatic differentiation for evaluation of the Jacobians.
228
double
errorValue[Edge::Dimension];
229
using
AutoDiffDims =
ceres::internal::StaticParameterDims
<
230
Edge::template VertexXnType<Ints>::Dimension...>;
231
bool
diffState =
232
ceres::internal::AutoDifferentiate
<Edge::Dimension, AutoDiffDims, Edge,
233
double
>(
234
*that, parameters, Edge::Dimension, errorValue, jacobians);
235
236
assert(diffState &&
"Error during Automatic Differentiation"
);
237
if
(!diffState) {
// something went wrong during AD
238
(void(std::get<Ints>(ad_jacobians).setZero()), ...);
239
return
;
240
}
241
// copy over the Jacobians (convert row-major -> column-major) for non-fixed
242
// vertices
243
(void(that->template vertexXn<Ints>()->fixed()
244
? (that->template jacobianOplusXn<Ints>().setZero(), 0)
245
: (
assign
(that->template jacobianOplusXn<Ints>(),
246
std::get<Ints>(ad_jacobians)),
247
0)),
248
...);
249
}
250
252
template
<
typename
A,
typename
B>
253
static
EIGEN_STRONG_INLINE
void
assign
(
const
Eigen::MatrixBase<A>& a,
254
const
Eigen::MatrixBase<B>& b) {
255
Eigen::MatrixBase<A>& aux =
const_cast<
Eigen::MatrixBase<A>&
>
(a);
256
aux = b;
257
}
258
};
259
260
}
// namespace g2o
261
262
// helper macros for fine-grained integration into own types
263
#define G2O_MAKE_AUTO_AD_COMPUTEERROR \
264
void computeError() override { \
265
g2o::AutoDifferentiation< \
266
std::remove_reference<decltype(*this)>::type>::computeError(this); \
267
}
268
#define G2O_MAKE_AUTO_AD_LINEARIZEOPLUS \
269
void linearizeOplus() override { \
270
g2o::AutoDifferentiation< \
271
std::remove_reference<decltype(*this)>::type>::linearize(this); \
272
}
273
277
#define G2O_MAKE_AUTO_AD_FUNCTIONS \
278
G2O_MAKE_AUTO_AD_COMPUTEERROR \
279
G2O_MAKE_AUTO_AD_LINEARIZEOPLUS
280
281
// helper macros for fine-grained integration into own types using
282
// EstimateAccessorGet
283
#define G2O_MAKE_AUTO_AD_COMPUTEERROR_BY_GET \
284
void computeError() override { \
285
using EdgeType = std::remove_reference<decltype(*this)>::type; \
286
g2o::AutoDifferentiation< \
287
EdgeType, g2o::EstimateAccessorGet<EdgeType>>::computeError(this); \
288
}
289
290
#define G2O_MAKE_AUTO_AD_LINEARIZEOPLUS_BY_GET \
291
void linearizeOplus() override { \
292
using EdgeType = std::remove_reference<decltype(*this)>::type; \
293
g2o::AutoDifferentiation< \
294
EdgeType, g2o::EstimateAccessorGet<EdgeType>>::linearize(this); \
295
}
296
300
#define G2O_MAKE_AUTO_AD_FUNCTIONS_BY_GET \
301
G2O_MAKE_AUTO_AD_COMPUTEERROR_BY_GET \
302
G2O_MAKE_AUTO_AD_LINEARIZEOPLUS_BY_GET
303
304
#endif
autodiff.h
g2o::AutoDifferentiation
Implementation of Automatic Differentiation for edges in g2o.
Definition
auto_differentiation.h:155
g2o::AutoDifferentiation::ADJacobianType
typename Eigen::Matrix< double, EdgeDimension, VertexDimension, Eigen::RowMajor > ADJacobianType
type for the Jacobians during AD
Definition
auto_differentiation.h:159
g2o::AutoDifferentiation::linearize
static void linearize(Edge *that)
Definition
auto_differentiation.h:177
g2o::AutoDifferentiation::linearizeOplusNs
static void linearizeOplusNs(Edge *that, std::index_sequence< Ints... >)
Definition
auto_differentiation.h:198
g2o::AutoDifferentiation::computeError
static void computeError(Edge *that)
helper for computing the error based on the functor in the edge
Definition
auto_differentiation.h:164
g2o::AutoDifferentiation::assign
static EIGEN_STRONG_INLINE void assign(const Eigen::MatrixBase< A > &a, const Eigen::MatrixBase< B > &b)
helper function to perform a = b
Definition
auto_differentiation.h:253
g2o::AutoDifferentiation::computeErrorNs
static void computeErrorNs(Edge *that, std::index_sequence< Ints... >)
packed version to call the functor that evaluates the error function
Definition
auto_differentiation.h:186
g2o::EstimateAccessorGet
Definition
auto_differentiation.h:63
g2o::EstimateAccessorGet::Buffer
typename BufferType< std::make_index_sequence< Edge::_nr_of_vertices > >::type Buffer
Definition
auto_differentiation.h:84
g2o::EstimateAccessorGet::data
EIGEN_STRONG_INLINE double * data(Edge *that)
Definition
auto_differentiation.h:66
g2o::EstimateAccessorGet::_estimateBuffer
Buffer _estimateBuffer
Definition
auto_differentiation.h:86
eigen_types.h
g2o_core_api.h
misc.h
some general case utility functions
g2o::ceres::internal::StaticParameterDims
ParameterDims< false, Ns... > StaticParameterDims
Definition
parameter_dims.h:119
g2o::ceres::internal::AutoDifferentiate
bool AutoDifferentiate(const Functor &functor, T const *const *parameters, int dynamic_num_outputs, T *function_value, T **jacobians)
Definition
autodiff.h:295
g2o
Definition
dl_wrapper.cpp:55
std
Definition
jet.h:876
g2o::EstimateAccessorGet::BufferType< std::index_sequence< Ints... > >::type
std::tuple< VectorN< Edge::template VertexXnType< Ints >::Dimension >... > type
Definition
auto_differentiation.h:80
g2o::EstimateAccessorGet::BufferType
Definition
auto_differentiation.h:77
g2o::EstimateAccessor
Definition
auto_differentiation.h:46
g2o::EstimateAccessor::data
EIGEN_STRONG_INLINE double * data(Edge *that)
Definition
auto_differentiation.h:48
Generated on
for g2o by
1.17.0