diff --git a/sophus/ceres_local_parameterization.hpp b/sophus/ceres_local_parameterization.hpp new file mode 100644 index 000000000..78e583b73 --- /dev/null +++ b/sophus/ceres_local_parameterization.hpp @@ -0,0 +1,101 @@ +#ifndef SOPHUS_CERES_LOCAL_PARAMETERIZATION_HPP +#define SOPHUS_CERES_LOCAL_PARAMETERIZATION_HPP + +#include + +namespace Sophus { + +template +constexpr std::true_type complete(T*); +constexpr std::false_type complete(...); + +template +using IsSpecialized = decltype(complete(std::declval())); + +/// Type trait used to distinguish mappable vector types from scalars +/// +/// We use this class to distinguish Sophus::Vector from Scalar types +/// in LieGroup::Tangent +/// +/// Primary use is mapping LieGroup::Tangent over raw data, with 2 options: +/// - LieGroup::Tangent is "scalar" (for SO2), then we just dereference pointer +/// - LieGroup::Tangent is Sophus::Vector<...>, then we need to use Eigen::Map +/// +/// Specialization of Eigen::internal::traits for T is crucial for +/// for constructing Eigen::Map, thus we use that property for distinguishing +/// between those two options. +/// At this moment there seem to be no option to check this using only +/// "external" API of Eigen +template +using IsMappable = IsSpecialized>>; + +template +constexpr bool IsMappableV = IsMappable::value; + +/// Helper for mapping tangent vectors (scalars) over pointers to data +template +struct Mapper { + using Scalar = T; + using Map = Scalar&; + using ConstMap = const Scalar&; + + static Map map(Scalar* ptr) noexcept { return *ptr; } + static ConstMap map(const Scalar* ptr) noexcept { return *ptr; } +}; + +template +struct Mapper>::type> { + using Scalar = typename T::Scalar; + using Map = Eigen::Map; + using ConstMap = Eigen::Map; + + static Map map(Scalar* ptr) noexcept { return Map(ptr); } + static ConstMap map(const Scalar* ptr) noexcept { return ConstMap(ptr); } +}; + +/// Templated local parameterization for LieGroup [with implemented +/// LieGroup::Dx_this_mul_exp_x_at_0() ] +template