Program Listing for File cartesian.hpp
↰ Return to documentation for file (sophus/cartesian.hpp
)
#pragma once
#include <sophus/types.hpp>
namespace Sophus {
template <class Scalar_, int M, int Options = 0>
class Cartesian;
template <class Scalar_>
using Cartesian2 = Cartesian<Scalar_, 2>;
template <class Scalar_>
using Cartesian3 = Cartesian<Scalar_, 3>;
using Cartesian2d = Cartesian2<double>;
using Cartesian3d = Cartesian3<double>;
} // namespace Sophus
namespace Eigen {
namespace internal {
template <class Scalar_, int M, int Options>
struct traits<Sophus::Cartesian<Scalar_, M, Options>> {
using Scalar = Scalar_;
using ParamsType = Sophus::Vector<Scalar, M, Options>;
};
template <class Scalar_, int M, int Options>
struct traits<Map<Sophus::Cartesian<Scalar_, M>, Options>>
: traits<Sophus::Cartesian<Scalar_, M, Options>> {
using Scalar = Scalar_;
using ParamsType = Map<Sophus::Vector<Scalar, M>, Options>;
};
template <class Scalar_, int M, int Options>
struct traits<Map<Sophus::Cartesian<Scalar_, M> const, Options>>
: traits<Sophus::Cartesian<Scalar_, M, Options> const> {
using Scalar = Scalar_;
using ParamsType = Map<Sophus::Vector<Scalar, M> const, Options>;
};
} // namespace internal
} // namespace Eigen
namespace Sophus {
// (M+1) x (M+1) homogeneous matrix:
template <class Derived, int M>
class CartesianBase {
public:
using Scalar = typename Eigen::internal::traits<Derived>::Scalar;
using ParamsType = typename Eigen::internal::traits<Derived>::ParamsType;
static int constexpr DoF = M;
static int constexpr num_parameters = M;
static int constexpr N = M + 1;
static int constexpr Dim = M;
using Transformation = Sophus::Matrix<Scalar, N, N>;
using Point = Sophus::Vector<Scalar, M>;
using HomogeneousPoint = Sophus::Vector<Scalar, N>;
using Line = ParametrizedLine<Scalar, M>;
using Hyperplane = Eigen::Hyperplane<Scalar, M>;
using Tangent = Sophus::Vector<Scalar, DoF>;
using Adjoint = Matrix<Scalar, DoF, DoF>;
template <typename OtherDerived>
using ReturnScalar = typename Eigen::ScalarBinaryOpTraits<
Scalar, typename OtherDerived::Scalar>::ReturnType;
template <typename OtherDerived>
using CartesianSum = Cartesian<ReturnScalar<OtherDerived>, M>;
template <typename PointDerived>
using PointProduct = Sophus::Vector<ReturnScalar<PointDerived>, M>;
template <typename HPointDerived>
using HomogeneousPointProduct =
Sophus::Vector<ReturnScalar<HPointDerived>, N>;
SOPHUS_FUNC Adjoint Adj() const { return Adjoint::Identity(); }
template <class NewScalarType>
SOPHUS_FUNC Cartesian<NewScalarType, M> cast() const {
return Cartesian<NewScalarType, M>(params().template cast<NewScalarType>());
}
SOPHUS_FUNC Matrix<Scalar, num_parameters, DoF> Dx_this_mul_exp_x_at_0()
const {
Sophus::Matrix<Scalar, num_parameters, DoF> m;
m.setIdentity();
return m;
}
SOPHUS_FUNC Matrix<Scalar, num_parameters, DoF> Dx_log_this_inv_by_x_at_this()
const {
Matrix<Scalar, DoF, num_parameters> m;
m.setIdentity();
return m;
}
SOPHUS_FUNC Cartesian<Scalar, M> inverse() const {
return Cartesian<Scalar, M>(-params());
}
SOPHUS_FUNC Tangent log() const { return params(); }
SOPHUS_FUNC Transformation matrix() const {
Sophus::Matrix<Scalar, N, N> matrix;
matrix.setIdentity();
matrix.col(M).template head<M>() = params();
return matrix;
}
template <class OtherDerived>
SOPHUS_FUNC CartesianBase<Derived, M>& operator=(
CartesianBase<OtherDerived, M> const& other) {
params() = other.params();
return *this;
}
template <typename OtherDerived>
SOPHUS_FUNC CartesianSum<OtherDerived> operator*(
CartesianBase<OtherDerived, M> const& other) const {
return CartesianSum<OtherDerived>(params() + other.params());
}
template <typename PointDerived,
typename = typename std::enable_if<
IsFixedSizeVector<PointDerived, M>::value>::type>
SOPHUS_FUNC PointProduct<PointDerived> operator*(
Eigen::MatrixBase<PointDerived> const& p) const {
return PointProduct<PointDerived>(params() + p);
}
template <typename HPointDerived,
typename = typename std::enable_if<
IsFixedSizeVector<HPointDerived, N>::value>::type>
SOPHUS_FUNC HomogeneousPointProduct<HPointDerived> operator*(
Eigen::MatrixBase<HPointDerived> const& p) const {
const auto rp = *this * p.template head<M>();
HomogeneousPointProduct<HPointDerived> r;
r << rp, p(M);
return r;
}
SOPHUS_FUNC Line operator*(Line const& l) const {
return Line((*this) * l.origin(), l.direction());
}
SOPHUS_FUNC Hyperplane operator*(Hyperplane const& p) const {
return Hyperplane(p.normal(), p.offset() - params().dot(p.normal()));
}
template <typename OtherDerived,
typename = typename std::enable_if<
std::is_same<Scalar, ReturnScalar<OtherDerived>>::value>::type>
SOPHUS_FUNC CartesianBase<Derived, M>& operator*=(
CartesianBase<OtherDerived, M> const& other) {
*static_cast<Derived*>(this) = *this * other;
return *this;
}
SOPHUS_FUNC ParamsType& params() {
return static_cast<Derived*>(this)->params();
}
SOPHUS_FUNC ParamsType const& params() const {
return static_cast<Derived const*>(this)->params();
}
};
template <class Scalar_, int M, int Options>
class Cartesian : public CartesianBase<Cartesian<Scalar_, M, Options>, M> {
using Base = CartesianBase<Cartesian<Scalar_, M, Options>, M>;
public:
static int constexpr DoF = Base::DoF;
static int constexpr num_parameters = Base::num_parameters;
static int constexpr N = Base::N;
static int constexpr Dim = Base::Dim;
using Scalar = Scalar_;
using Transformation = typename Base::Transformation;
using Point = typename Base::Point;
using HomogeneousPoint = typename Base::HomogeneousPoint;
using Tangent = typename Base::Tangent;
using ParamsMember = Sophus::Vector<Scalar, M, Options>;
using Base::operator=;
SOPHUS_FUNC Cartesian& operator=(Cartesian const& other) = default;
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
SOPHUS_FUNC Cartesian() { params_.setZero(); }
SOPHUS_FUNC Cartesian(Cartesian const& other) = default;
template <class OtherDerived>
SOPHUS_FUNC Cartesian(CartesianBase<OtherDerived, M> const& other)
: params_(other.params()) {
static_assert(std::is_same<typename OtherDerived::Scalar, Scalar>::value,
"must be same Scalar type");
}
template <class D>
explicit SOPHUS_FUNC Cartesian(Eigen::MatrixBase<D> const& m) {
static_assert(
std::is_same<typename Eigen::MatrixBase<D>::Scalar, Scalar>::value, "");
if (m.rows() == DoF && m.cols() == 1) {
// trick so this compiles
params_ = m.template block<M, 1>(0, 0);
} else if (m.rows() == N && m.cols() == N) {
params_ = m.template block<M, 1>(0, M);
} else {
SOPHUS_ENSURE(false, "{} {}", m.rows(), m.cols());
}
}
SOPHUS_FUNC Scalar* data() { return params_.data(); }
SOPHUS_FUNC Scalar const* data() const { return params_.data(); }
SOPHUS_FUNC static Sophus::Matrix<Scalar, num_parameters, DoF>
Dx_exp_x_at_0() {
Sophus::Matrix<Scalar, num_parameters, DoF> m;
m.setIdentity();
return m;
}
SOPHUS_FUNC static Sophus::Matrix<Scalar, num_parameters, DoF> Dx_exp_x(
Tangent const&) {
return Dx_exp_x_at_0();
}
SOPHUS_FUNC static Sophus::Matrix<Scalar, Dim, DoF> Dx_exp_x_times_point_at_0(
Point const&) {
Sophus::Matrix<Scalar, Dim, DoF> J;
J.setIdentity();
return J;
}
SOPHUS_FUNC static Transformation Dxi_exp_x_matrix_at_0(int i) {
return generator(i);
}
SOPHUS_FUNC ParamsMember& params() { return params_; }
SOPHUS_FUNC ParamsMember const& params() const { return params_; }
SOPHUS_FUNC static Transformation generator(int i) {
SOPHUS_ENSURE(i >= 0 && i <= M, "i should be in range [0,M-1].");
Tangent e;
e.setZero();
e[i] = Scalar(1);
return hat(e);
}
// from the M-vector.
SOPHUS_FUNC static Cartesian<Scalar, M> exp(Tangent const& a) {
return Cartesian<Scalar, M>(a);
}
SOPHUS_FUNC static Transformation hat(Tangent const& a) {
Transformation Omega;
Omega.setZero();
Omega.col(M).template head<M>() = a.template head<M>();
return Omega;
}
SOPHUS_FUNC static Tangent lieBracket(Tangent const&, Tangent const&) {
return Tangent::Zero();
}
template <class UniformRandomBitGenerator>
static Cartesian sampleUniform(UniformRandomBitGenerator& generator) {
std::uniform_real_distribution<Scalar> uniform(Scalar(-1), Scalar(1));
Vector<Scalar, M> v;
for (int i = 0; i < M; ++i) {
v[i] = uniform(generator);
}
return Cartesian(v);
}
SOPHUS_FUNC static Tangent vee(Transformation const& m) {
return m.col(M).template head<M>();
}
protected:
ParamsMember params_;
};
} // namespace Sophus
namespace Eigen {
template <class Scalar_, int M, int Options>
class Map<Sophus::Cartesian<Scalar_, M>, Options>
: public Sophus::CartesianBase<Map<Sophus::Cartesian<Scalar_, M>, Options>,
M> {
public:
using Base =
Sophus::CartesianBase<Map<Sophus::Cartesian<Scalar_, M>, Options>, M>;
using Scalar = Scalar_;
using Transformation = typename Base::Transformation;
using Point = typename Base::Point;
using HomogeneousPoint = typename Base::HomogeneousPoint;
using Tangent = typename Base::Tangent;
using Base::operator=;
using Base::operator*=;
using Base::operator*;
SOPHUS_FUNC explicit Map(Scalar* coeffs) : params_(coeffs) {}
SOPHUS_FUNC Map<Sophus::Vector<Scalar, M, Options>>& params() {
return params_;
}
SOPHUS_FUNC Map<Sophus::Vector<Scalar, M, Options>> const& params() const {
return params_;
}
protected:
Map<Sophus::Vector<Scalar, M>, Options> params_;
};
template <class Scalar_, int M, int Options>
class Map<Sophus::Cartesian<Scalar_, M> const, Options>
: public Sophus::CartesianBase<
Map<Sophus::Cartesian<Scalar_, M> const, Options>, M> {
public:
using Base =
Sophus::CartesianBase<Map<Sophus::Cartesian<Scalar_, M> const, Options>,
M>;
using Scalar = Scalar_;
using Transformation = typename Base::Transformation;
using Point = typename Base::Point;
using HomogeneousPoint = typename Base::HomogeneousPoint;
using Tangent = typename Base::Tangent;
using Base::operator*;
SOPHUS_FUNC Map(Scalar const* coeffs) : params_(coeffs) {}
SOPHUS_FUNC Map<Sophus::Vector<Scalar, M> const, Options> const& params()
const {
return params_;
}
protected:
Map<Sophus::Vector<Scalar, M> const, Options> const params_;
};
} // namespace Eigen