136 lines
4.7 KiB
C++
136 lines
4.7 KiB
C++
/* ----------------------------------------------------------------------------
|
|
|
|
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
|
* Atlanta, Georgia 30332-0415
|
|
* All Rights Reserved
|
|
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
|
|
|
* See LICENSE for the license information
|
|
|
|
* -------------------------------------------------------------------------- */
|
|
|
|
/*
|
|
* @file ReferenceFrameFactor.h
|
|
* @brief A constraint for combining graphs by common landmarks and a transform node
|
|
* @author Alex Cunningham
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
|
|
|
namespace gtsam {
|
|
|
|
/**
|
|
* Transform function that must be specialized specific domains
|
|
* @tparam T is a Transform type
|
|
* @tparam P is a point type
|
|
*/
|
|
template<class T, class P>
|
|
P transform_point(
|
|
const T& trans, const P& global,
|
|
boost::optional<Matrix&> Dtrans,
|
|
boost::optional<Matrix&> Dglobal) {
|
|
return trans.transformFrom(global, Dtrans, Dglobal);
|
|
}
|
|
|
|
/**
|
|
* A constraint between two landmarks in separate maps
|
|
* Templated on:
|
|
* Point : Type of landmark
|
|
* Transform : Transform variable class
|
|
*
|
|
* The transform is defined as transforming global to local:
|
|
* l = lTg * g
|
|
*
|
|
* The Point and Transform concepts must be Lie types, and the transform
|
|
* relationship "Point = transformFrom(Transform, Point)" must exist.
|
|
*
|
|
* To implement this function in new domains, specialize a new version of
|
|
* Point transform_point<Transform,Point>(transform, global, Dtrans, Dglobal)
|
|
* to use the correct point and transform types.
|
|
*
|
|
* This base class should be specialized to implement the cost function for
|
|
* specific classes of landmarks
|
|
*/
|
|
template<class POINT, class TRANSFORM>
|
|
class ReferenceFrameFactor : public NoiseModelFactorN<POINT, TRANSFORM, POINT> {
|
|
protected:
|
|
/** default constructor for serialization only */
|
|
ReferenceFrameFactor() {}
|
|
|
|
public:
|
|
typedef NoiseModelFactorN<POINT, TRANSFORM, POINT> Base;
|
|
typedef ReferenceFrameFactor<POINT, TRANSFORM> This;
|
|
|
|
typedef POINT Point;
|
|
typedef TRANSFORM Transform;
|
|
|
|
/**
|
|
* General constructor with arbitrary noise model (constrained or otherwise)
|
|
*/
|
|
ReferenceFrameFactor(Key globalKey, Key transKey, Key localKey, const noiseModel::Base::shared_ptr& model)
|
|
: Base(model,globalKey, transKey, localKey) {}
|
|
|
|
/**
|
|
* Construct a hard frame of reference reference constraint with equal mu values for
|
|
* each degree of freedom.
|
|
*/
|
|
ReferenceFrameFactor(double mu, Key globalKey, Key transKey, Key localKey)
|
|
: Base(globalKey, transKey, localKey, Point().dim(), mu) {}
|
|
|
|
/**
|
|
* Simple soft constraint constructor for frame of reference, with equal weighting for
|
|
* each degree of freedom.
|
|
*/
|
|
ReferenceFrameFactor(Key globalKey, Key transKey, Key localKey, double sigma = 1e-2)
|
|
: Base(noiseModel::Isotropic::Sigma(traits<POINT>::dimension, sigma),
|
|
globalKey, transKey, localKey) {}
|
|
|
|
~ReferenceFrameFactor() override{}
|
|
|
|
NonlinearFactor::shared_ptr clone() const override {
|
|
return boost::static_pointer_cast<NonlinearFactor>(
|
|
NonlinearFactor::shared_ptr(new This(*this))); }
|
|
|
|
/** Combined cost and derivative function using boost::optional */
|
|
Vector evaluateError(const Point& global, const Transform& trans, const Point& local,
|
|
boost::optional<Matrix&> Dforeign = boost::none,
|
|
boost::optional<Matrix&> Dtrans = boost::none,
|
|
boost::optional<Matrix&> Dlocal = boost::none) const override {
|
|
Point newlocal = transform_point<Transform,Point>(trans, global, Dtrans, Dforeign);
|
|
if (Dlocal)
|
|
*Dlocal = -1* Matrix::Identity(traits<Point>::dimension, traits<Point>::dimension);
|
|
return traits<Point>::Local(local,newlocal);
|
|
}
|
|
|
|
void print(const std::string& s="",
|
|
const gtsam::KeyFormatter& keyFormatter = DefaultKeyFormatter) const override {
|
|
std::cout << s << ": ReferenceFrameFactor("
|
|
<< "Global: " << keyFormatter(this->template key<1>()) << ","
|
|
<< " Transform: " << keyFormatter(this->template key<2>()) << ","
|
|
<< " Local: " << keyFormatter(this->template key<3>()) << ")\n";
|
|
this->noiseModel_->print(" noise model");
|
|
}
|
|
|
|
// access - convenience functions
|
|
Key global_key() const { return this->template key<1>(); }
|
|
Key transform_key() const { return this->template key<2>(); }
|
|
Key local_key() const { return this->template key<3>(); }
|
|
|
|
private:
|
|
/** Serialization function */
|
|
friend class boost::serialization::access;
|
|
template<class ARCHIVE>
|
|
void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
|
|
ar & boost::serialization::make_nvp("NonlinearFactor3",
|
|
boost::serialization::base_object<Base>(*this));
|
|
}
|
|
};
|
|
|
|
/// traits
|
|
template<class T1, class T2>
|
|
struct traits<ReferenceFrameFactor<T1, T2> > : public Testable<ReferenceFrameFactor<T1, T2> > {};
|
|
|
|
} // \namespace gtsam
|