Skip to content

Commit 2c652c7

Browse files
Gcc12 ceres 2.1.0 manifold locus (#363)
* General clean up for Ceres 2.2.0 support * Updated serialization support to be backwards compatible with previously serialized files --------- Co-authored-by: Enrique Fernandez Perdomo <[email protected]>
1 parent 522a2ec commit 2c652c7

File tree

52 files changed

+1916
-652
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1916
-652
lines changed

fuse_constraints/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ if(CATKIN_ENABLE_TESTING)
336336
# Marginal Constraint Tests
337337
catkin_add_gtest(test_marginal_constraint
338338
test/test_marginal_constraint.cpp
339+
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/test
339340
)
340341
add_dependencies(test_marginal_constraint
341342
${catkin_EXPORTED_TARGETS}

fuse_constraints/include/fuse_constraints/marginal_constraint.h

Lines changed: 76 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <fuse_core/fuse_macros.h>
4040
#include <fuse_core/local_parameterization.h>
4141
#include <fuse_core/manifold.h>
42+
#include <fuse_core/manifold_adapter.h>
4243
#include <fuse_core/serialization.h>
4344
#include <fuse_core/variable.h>
4445

@@ -48,14 +49,19 @@
4849
#include <boost/serialization/base_object.hpp>
4950
#include <boost/serialization/export.hpp>
5051
#include <boost/serialization/shared_ptr.hpp>
52+
#include <boost/serialization/unique_ptr.hpp>
5153
#include <boost/serialization/vector.hpp>
5254
#include <boost/tuple/tuple.hpp>
5355
#include <ceres/cost_function.h>
5456

5557
#include <algorithm>
5658
#include <cassert>
59+
#include <functional>
60+
#include <iterator>
5761
#include <ostream>
62+
#include <stdexcept>
5863
#include <string>
64+
#include <utility>
5965
#include <vector>
6066

6167
namespace fuse_constraints
@@ -131,7 +137,7 @@ class MarginalConstraint : public fuse_core::Constraint
131137
}
132138
#else
133139
/**
134-
* @brief Read-only access to the variable local parameterizations
140+
* @brief Read-only access to the variable manifolds
135141
*/
136142
const std::vector<fuse_core::Manifold::SharedPtr>& manifolds() const { return manifolds_; }
137143
#endif
@@ -171,22 +177,72 @@ class MarginalConstraint : public fuse_core::Constraint
171177
/**
172178
* @brief The Boost Serialize method that serializes all of the data members in to/out of the archive
173179
*
174-
* @param[in/out] archive - The archive object that holds the serialized class members
175-
* @param[in] version - The version of the archive being read/written. Generally unused.
180+
* @param[out] archive - The archive object into which class members will be serialized
181+
* @param[in] version - The version of the archive being written.
176182
*/
177-
template <class Archive>
178-
void serialize(Archive& archive, const unsigned int /* version */)
183+
template<class Archive>
184+
void save(Archive& archive, const unsigned int version) const
179185
{
180-
archive& boost::serialization::base_object<fuse_core::Constraint>(*this);
181-
archive& A_;
182-
archive& b_;
186+
archive << boost::serialization::base_object<fuse_core::Constraint>(*this);
187+
archive << A_;
188+
archive << b_;
183189
#if !CERES_SUPPORTS_MANIFOLDS
184-
archive& local_parameterizations_;
190+
archive << local_parameterizations_;
185191
#else
186-
archive& manifolds_;
192+
archive << manifolds_;
187193
#endif
188-
archive& x_bar_;
194+
archive << x_bar_;
189195
}
196+
197+
/**
198+
* @brief The Boost Serialize method that serializes all of the data members in to/out of the archive
199+
*
200+
* @param[in] archive - The archive object that holds the serialized class members
201+
* @param[in] version - The version of the archive being read.
202+
*/
203+
template<class Archive>
204+
void load(Archive& archive, const unsigned int version)
205+
{
206+
archive >> boost::serialization::base_object<fuse_core::Constraint>(*this);
207+
archive >> A_;
208+
archive >> b_;
209+
if (version == 0)
210+
{
211+
// Version 0 serialization files will contain a std::vector of LocalParameterization shared pointers.
212+
// If the current version of Ceres Solver does not support Manifolds, then the serialized LocalParameterization
213+
// pointers can be deserialized directly into the class member.
214+
// But if the current version of Ceres Solver supports manifolds, then the serialized LocalParameterization
215+
// pointers must be wrapped in a Manifold adapter first.
216+
#if !CERES_SUPPORTS_MANIFOLDS
217+
archive >> local_parameterizations_;
218+
#else
219+
auto local_parameterizations = std::vector<fuse_core::LocalParameterization::SharedPtr>();
220+
archive >> local_parameterizations;
221+
std::transform(
222+
std::make_move_iterator(local_parameterizations.begin()),
223+
std::make_move_iterator(local_parameterizations.end()),
224+
std::back_inserter(manifolds_),
225+
[](fuse_core::LocalParameterization::SharedPtr local_parameterization)
226+
{ return fuse_core::ManifoldAdapter::make_shared(std::move(local_parameterization)); });
227+
#endif
228+
}
229+
else // (version >= 1)
230+
{
231+
// Version 1 serialization files will contain a std::vector of Manifold shared pointers. If the current version
232+
// of Ceres Solver does not support Manifolds, then there is no way to deserialize the requested data.
233+
// But if the current version of Ceres Solver does support manifolds, then the serialized Manifold pointers
234+
// can be deserialized directly into the class member.
235+
#if !CERES_SUPPORTS_MANIFOLDS
236+
throw std::runtime_error("Attempting to deserialize an archive saved in Version " + std::to_string(version) +
237+
" format. However, the current version of Ceres Solver (" + CERES_VERSION_STRING + ") does not support"
238+
" manifolds. Ceres Solver version 2.1.0 or later is required to load this file.");
239+
#else
240+
archive >> manifolds_;
241+
#endif
242+
}
243+
archive >> x_bar_;
244+
}
245+
BOOST_SERIALIZATION_SPLIT_MEMBER();
190246
};
191247

192248
namespace detail
@@ -211,7 +267,7 @@ inline const fuse_core::VectorXd getCurrentValue(const fuse_core::Variable& vari
211267
/**
212268
* @brief Return the local parameterization of the provided variable
213269
*/
214-
inline fuse_core::LocalParameterization::SharedPtr const getLocalParameterization(const fuse_core::Variable& variable)
270+
inline fuse_core::LocalParameterization::SharedPtr getLocalParameterization(const fuse_core::Variable& variable)
215271
{
216272
return fuse_core::LocalParameterization::SharedPtr(variable.localParameterization());
217273
}
@@ -220,7 +276,7 @@ inline fuse_core::LocalParameterization::SharedPtr const getLocalParameterizatio
220276
/**
221277
* @brief Return the manifold of the provided variable
222278
*/
223-
inline fuse_core::Manifold::SharedPtr const getManifold(const fuse_core::Variable& variable)
279+
inline fuse_core::Manifold::SharedPtr getManifold(const fuse_core::Variable& variable)
224280
{
225281
return fuse_core::Manifold::SharedPtr(variable.manifold());
226282
}
@@ -275,5 +331,12 @@ MarginalConstraint::MarginalConstraint(
275331
} // namespace fuse_constraints
276332

277333
BOOST_CLASS_EXPORT_KEY(fuse_constraints::MarginalConstraint);
334+
// Since the contents of the serialized file will change depending on the CeresSolver version, also set the
335+
// Boost Serialization version to allow code reading serialized file to know what data to expect.
336+
#if !CERES_SUPPORTS_MANIFOLDS
337+
BOOST_CLASS_VERSION(fuse_constraints::MarginalConstraint, 0);
338+
#else
339+
BOOST_CLASS_VERSION(fuse_constraints::MarginalConstraint, 1);
340+
#endif
278341

279342
#endif // FUSE_CONSTRAINTS_MARGINAL_CONSTRAINT_H

fuse_constraints/include/fuse_constraints/marginal_cost_function.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ class MarginalCostFunction : public ceres::CostFunction
8181
/**
8282
* @brief Construct a cost function instance
8383
*
84-
* @param[in] A The A matrix of the marginal cost (of the form A*(x - x_bar) + b)
85-
* @param[in] b The b vector of the marginal cost (of the form A*(x - x_bar) + b)
86-
* @param[in] x_bar The linearization point of the involved variables
87-
* @param[in] manifolds The manifold associated with the variable
84+
* @param[in] A The A matrix of the marginal cost (of the form A*(x - x_bar) + b)
85+
* @param[in] b The b vector of the marginal cost (of the form A*(x - x_bar) + b)
86+
* @param[in] x_bar The linearization point of the involved variables
87+
* @param[in] manifolds The manifold associated with the variable
8888
*/
8989
MarginalCostFunction(
9090
const std::vector<fuse_core::MatrixXd>& A,
@@ -102,7 +102,10 @@ class MarginalCostFunction : public ceres::CostFunction
102102
* @brief Compute the cost values/residuals, and optionally the Jacobians, using the provided variable/parameter
103103
* values
104104
*/
105-
bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const override;
105+
bool Evaluate(
106+
double const* const* parameters,
107+
double* residuals,
108+
double** jacobians) const override;
106109

107110
private:
108111
const std::vector<fuse_core::MatrixXd>& A_; //!< The A matrices of the marginal cost

fuse_constraints/src/marginal_constraint.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,8 @@ void MarginalConstraint::print(std::ostream& stream) const
5757
Eigen::IOFormat indent(4, 0, ", ", "\n", " [", "]");
5858
for (size_t i = 0; i < A().size(); ++i)
5959
{
60-
stream << " A[" << i << "]:\n"
61-
<< A()[i].format(indent) << "\n"
62-
<< " x_bar[" << i << "]:\n"
63-
<< x_bar()[i].format(indent) << "\n";
60+
stream << " A[" << i << "]:\n" << A()[i].format(indent) << "\n"
61+
<< " x_bar[" << i << "]:\n" << x_bar()[i].format(indent) << "\n";
6462
}
6563
stream << " b:\n" << b().format(indent) << "\n";
6664

fuse_constraints/src/marginal_cost_function.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,10 @@ MarginalCostFunction::MarginalCostFunction(
7979
}
8080
#endif
8181

82-
bool MarginalCostFunction::Evaluate(double const* const* parameters, double* residuals, double** jacobians) const
82+
bool MarginalCostFunction::Evaluate(
83+
double const* const* parameters,
84+
double* residuals,
85+
double** jacobians) const
8386
{
8487
// Compute cost
8588
Eigen::Map<fuse_core::VectorXd> residuals_map(residuals, num_residuals());

fuse_constraints/src/marginalize_variables.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,10 @@ UuidOrdering computeEliminationOrder(
103103
}
104104

105105
// Construct the CCOLAMD input structures
106-
auto recommended_size =
107-
ccolamd_recommended(variable_constraints.size(), constraint_order.size(), variable_order.size());
106+
auto recommended_size = ccolamd_recommended(
107+
variable_constraints.size(),
108+
constraint_order.size(),
109+
variable_order.size());
108110
auto A = std::vector<int>(recommended_size);
109111
auto p = std::vector<int>(variable_order.size() + 1);
110112

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
22 serialization::archive 17 1 0
2+
0 0 0 4 test 68a8f481-d9e2-434e-96d8-d9c52fac6603 0 0 1 0 d0344d9a-5584-5a24-b972-ea410b25e499 0 1 -1 0 0 1 0 0 0 1 3 5.00000000000000000e+00 6.00000000000000000e+00 7.00000000000000000e+00 0 0 1 1 8.00000000000000000e+00 0 0 1 1 0 1 9 50 fuse_variables::Orientation3DLocalParameterization 1 0
3+
1 0 0 0 0 1 0 4 1 8.42614976999999987e-01 2.00000000000000011e-01 2.99999999999999989e-01 4.00000000000000022e-01

0 commit comments

Comments
 (0)