26 requires concepts::LieFactorGroupImpl<TFactorGroup<TScalar>>
34 static_assert(
kPointDim == FactorGroup::kPointDim);
35 static_assert(
kPointDim == FactorGroup::kAmbientDim);
40 static_cast<bool>(FactorGroup::kIsOriginPreserving),
41 "The factor group is origin preserving by definition.");
43 FactorGroup::kIsAxisDirectionPreserving;
45 FactorGroup::kIsDirectionVectorPreserving;
50 static_cast<bool>(FactorGroup::kIisParallelLinePreserving),
51 "The factor group by definition needs to map parallel lines to parallel "
52 "lines. In particular projective mappings are not allowed.");
59 using Tangent = Eigen::Vector<Scalar, kDof>;
60 using Params = Eigen::Vector<Scalar, kNumParams>;
61 using Point = Eigen::Vector<Scalar, kPointDim>;
63 template <
class TCompatibleScalar>
65 ScalarBinaryOpTraits<Scalar, TCompatibleScalar>::ReturnType;
67 template <
class TCompatibleScalar>
69 Eigen::Vector<ScalarReturn<TCompatibleScalar>,
kNumParams>;
71 template <
class TCompatibleScalar>
74 template <
class TCompatibleScalar>
81 return params(FactorGroup::identityParams(), Point::Zero().
eval());
85 -> sophus::Expected<Success> {
86 return FactorGroup::areParamsValid(factorGroupParams(params));
90 return FactorGroup::hasShortestPathAmbiguity(factorGroupParams(params));
96 Eigen::Vector<Scalar, FactorGroup::kNumParams> factor_group_params =
97 FactorGroup::exp(factorTangent(tangent));
100 (FactorGroup::matV(factor_group_params, factorTangent(tangent)) *
101 translationTangent(tangent))
106 Eigen::Vector<Scalar, FactorGroup::kDof> factor_tangent =
107 FactorGroup::log(factorGroupParams(params));
109 FactorGroup::matVInverse(factorGroupParams(params), factor_tangent) *
115 -> Eigen::Matrix<Scalar, kAmbientDim, kAmbientDim> {
116 Eigen::Matrix<Scalar, kAmbientDim, kAmbientDim> hat_mat;
118 hat_mat.template topLeftCorner<kPointDim, kPointDim>() =
119 FactorGroup::hat(factorTangent(tangent));
120 hat_mat.template topRightCorner<kPointDim, 1>() =
121 translationTangent(tangent);
125 static auto vee(Eigen::Matrix<Scalar, kAmbientDim, kAmbientDim>
const& mat)
126 -> Eigen::Matrix<Scalar, kDof, 1> {
128 mat.template topRightCorner<kPointDim, 1>().eval(),
130 mat.template topLeftCorner<kPointDim, kPointDim>().eval()));
134 template <
class TCompatibleScalar>
137 Eigen::Vector<TCompatibleScalar, kNumParams>
const& rhs_params)
140 FactorGroup::multiplication(
141 factorGroupParams(lhs_params), factorGroupParams(rhs_params));
145 factorGroupParams(lhs_params), translation(rhs_params)) +
146 translation(lhs_params);
148 return TranslationFactorGroupProduct::params(p, t);
152 Eigen::Vector<Scalar, FactorGroup::kNumParams> factor_group_params =
153 FactorGroup::inverse(factorGroupParams(params));
154 return TranslationFactorGroupProduct::params(
156 (-FactorGroup::action(factor_group_params, translation(params)))
162 template <
class TCompatibleScalar>
165 Eigen::Matrix<TCompatibleScalar, kPointDim, 1>
const& point)
167 return FactorGroup::action(factorGroupParams(params), point) +
172 -> Eigen::Vector<Scalar, kAmbientDim> {
176 template <
class TCompatibleScalar>
181 return FactorGroup::action(factorGroupParams(params), direction);
184 static auto adj(
Params const& params) -> Eigen::Matrix<Scalar, kDof, kDof> {
185 Eigen::Matrix<Scalar, kDof, kDof> mat_adjoint;
187 Eigen::Vector<Scalar, FactorGroup::kNumParams> factor_group_params =
188 factorGroupParams(params);
190 mat_adjoint.template topLeftCorner<kPointDim, kPointDim>() =
191 FactorGroup::matrix(factor_group_params);
192 mat_adjoint.template topRightCorner<kPointDim, FactorGroup::kDof>() =
193 FactorGroup::adjOfTranslation(factor_group_params, translation(params));
195 mat_adjoint.template bottomLeftCorner<FactorGroup::kDof, kPointDim>()
198 .template bottomRightCorner<FactorGroup::kDof, FactorGroup::kDof>() =
199 FactorGroup::adj(factor_group_params);
204 static auto ad(
Tangent const& tangent) -> Eigen::Matrix<Scalar, kDof, kDof> {
205 Eigen::Matrix<Scalar, kDof, kDof>
ad;
206 ad.template topLeftCorner<kPointDim, kPointDim>() =
207 FactorGroup::hat(factorTangent(tangent));
208 ad.template topRightCorner<kPointDim, FactorGroup::kDof>() =
209 FactorGroup::adOfTranslation(translationTangent(tangent));
211 ad.template bottomLeftCorner<FactorGroup::kDof, kPointDim>().setZero();
213 ad.template bottomRightCorner<FactorGroup::kDof, FactorGroup::kDof>() =
214 FactorGroup::ad(factorTangent(tangent));
222 -> Eigen::Matrix<Scalar, kPointDim, kAmbientDim> {
223 Eigen::Matrix<Scalar, kPointDim, kAmbientDim> mat;
224 mat.template topLeftCorner<kPointDim, kPointDim>() =
225 FactorGroup::compactMatrix(factorGroupParams(params));
226 mat.template topRightCorner<kPointDim, 1>() = translation(params);
231 -> Eigen::Matrix<Scalar, kAmbientDim, kAmbientDim> {
232 Eigen::Matrix<Scalar, kAmbientDim, kAmbientDim> mat;
234 mat.template topLeftCorner<kPointDim, kAmbientDim>() =
252 static auto dxExpXAt0() -> Eigen::Matrix<Scalar, kNumParams, kDof> {
253 Eigen::Matrix<Scalar, kNumParams, kDof> j;
255 j.template topRightCorner<FactorGroup::kNumParams, FactorGroup::kDof>() =
256 FactorGroup::dxExpXAt0();
257 j.template bottomLeftCorner<kPointDim, kPointDim>().setIdentity();
262 -> Eigen::Matrix<Scalar, kPointDim, kDof> {
263 Eigen::Matrix<Scalar, kPointDim, kDof> j;
264 j.template topLeftCorner<kPointDim, kPointDim>().setIdentity();
265 j.template topRightCorner<kPointDim, FactorGroup::kDof>() =
266 FactorGroup::dxExpXTimesPointAt0(point);
271 -> Eigen::Matrix<Scalar, kNumParams, kDof> {
272 Eigen::Matrix<Scalar, kNumParams, kDof> j;
274 Eigen::Vector<Scalar, FactorGroup::kNumParams> factor_group_params =
275 factorGroupParams(params);
276 j.template topRightCorner<FactorGroup::kNumParams, FactorGroup::kDof>() =
277 FactorGroup::dxThisMulExpXAt0(factor_group_params);
278 j.template bottomLeftCorner<kPointDim, kPointDim>() =
279 FactorGroup::matrix(factor_group_params);
284 -> Eigen::Matrix<Scalar, kDof, kNumParams> {
285 Eigen::Matrix<Scalar, kDof, kNumParams> j;
287 Eigen::Vector<Scalar, FactorGroup::kNumParams> factor_group_params =
288 factorGroupParams(params);
289 j.template bottomLeftCorner<FactorGroup::kDof, FactorGroup::kNumParams>() =
290 FactorGroup::dxLogThisInvTimesXAtThis(factor_group_params);
291 j.template topRightCorner<kPointDim, kPointDim>() =
292 FactorGroup::matrix(factor_group_params).inverse();
299 std::vector<Tangent> examples;
300 for (
auto const& group_tangent : FactorGroup::tangentExamples()) {
301 for (
auto const& translation_tangents : exampleTranslations()) {
302 examples.push_back(tangent(translation_tangents, group_tangent));
309 std::vector<Params> examples;
310 for (
auto const& factor_group_params : FactorGroup::paramsExamples()) {
311 for (
auto const& right_params : exampleTranslations()) {
312 examples.push_back(params(factor_group_params, right_params));
319 std::vector<Params> examples;
320 for (
auto const& factor_group_params :
321 FactorGroup::invalidParamsExamples()) {
322 for (
auto const& right_params : exampleTranslations()) {
323 examples.push_back(params(factor_group_params, right_params));
330 template <
class TScalar2>
331 static auto factorGroupParams(
332 Eigen::Vector<TScalar2, kNumParams>
const& params)
333 -> Eigen::Vector<TScalar2, FactorGroup::kNumParams> {
334 return params.template head<FactorGroup::kNumParams>();
337 template <
class TScalar2>
338 static auto translation(Eigen::Vector<TScalar2, kNumParams>
const& params)
339 -> Eigen::Vector<TScalar2, kPointDim> {
340 return params.template tail<kPointDim>();
343 template <
class TScalar2>
345 Eigen::Vector<TScalar2, FactorGroup::kNumParams>
const&
347 Eigen::Vector<TScalar2, kPointDim>
const& translation)
348 -> Eigen::Vector<TScalar2, kNumParams> {
349 Eigen::Vector<TScalar2, kNumParams> params;
350 params.template head<FactorGroup::kNumParams>() = factor_grop_tarams;
351 params.template tail<kPointDim>() = translation;
355 static auto factorTangent(
Tangent const& tangent)
356 -> Eigen::Vector<Scalar, FactorGroup::kDof> {
357 return tangent.template tail<FactorGroup::kDof>();
360 static auto translationTangent(
Tangent const& tangent) ->
Point {
361 return tangent.template head<kPointDim>();
365 Point const& translation,
366 Eigen::Vector<Scalar, FactorGroup::kDof>
const& factor_tangent)
369 tangent.template head<kPointDim>() = translation;
370 tangent.template tail<FactorGroup::kDof>() = factor_tangent;
374 static auto exampleTranslations() -> std::vector<Point> {
375 return ::sophus::pointExamples<Scalar, kPointDim>();
379 template <
int kTranslationDim,
template <
class>
class TFactorGroup>
381 template <
class TScalar>