factor to constrain distance between two points
parent
e133e8c2e8
commit
86774e8e1d
|
|
@ -0,0 +1,88 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* 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 DistanceFactor.h
|
||||
* @author Duy-Nguyen Ta
|
||||
* @date Sep 26, 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
/**
|
||||
* Factor to constrain known measured distance between two points
|
||||
*/
|
||||
template<class POINT>
|
||||
class DistanceFactor: public NoiseModelFactor2<POINT, POINT> {
|
||||
|
||||
double measured_; /// measured distance
|
||||
|
||||
typedef NoiseModelFactor2<POINT, POINT> Base;
|
||||
typedef DistanceFactor<POINT> This;
|
||||
|
||||
public:
|
||||
/// Default constructor
|
||||
DistanceFactor() {
|
||||
}
|
||||
|
||||
/// Constructor with keys and known measured distance
|
||||
DistanceFactor(Key p1, Key p2, double measured, const SharedNoiseModel& model) :
|
||||
Base(model, p1, p2), measured_(measured) {
|
||||
}
|
||||
|
||||
/// @return a deep copy of this factor
|
||||
virtual gtsam::NonlinearFactor::shared_ptr clone() const {
|
||||
return boost::static_pointer_cast<gtsam::NonlinearFactor>(
|
||||
gtsam::NonlinearFactor::shared_ptr(new This(*this))); }
|
||||
|
||||
/// h(x)-z
|
||||
Vector evaluateError(const POINT& p1, const POINT& p2,
|
||||
boost::optional<Matrix&> H1 = boost::none, boost::optional<Matrix&> H2 =
|
||||
boost::none) const {
|
||||
double distance = p1.distance(p2, H1, H2);
|
||||
return (Vector(1) << distance - measured_);
|
||||
}
|
||||
|
||||
/** return the measured */
|
||||
double measured() const {
|
||||
return measured_;
|
||||
}
|
||||
|
||||
/** equals specialized to this factor */
|
||||
virtual bool equals(const NonlinearFactor& expected, double tol=1e-9) const {
|
||||
const This *e = dynamic_cast<const This*> (&expected);
|
||||
return e != NULL && Base::equals(*e, tol) && fabs(this->measured_ - e->measured_) < tol;
|
||||
}
|
||||
|
||||
/** print contents */
|
||||
void print(const std::string& s="", const KeyFormatter& keyFormatter = DefaultKeyFormatter) const {
|
||||
std::cout << s << "DistanceFactor, distance = " << measured_ << std::endl;
|
||||
Base::print("", keyFormatter);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** Serialization function */
|
||||
friend class boost::serialization::access;
|
||||
template<class ARCHIVE>
|
||||
void serialize(ARCHIVE & ar, const unsigned int version) {
|
||||
ar & boost::serialization::make_nvp("NoiseModelFactor2",
|
||||
boost::serialization::base_object<Base>(*this));
|
||||
ar & BOOST_SERIALIZATION_NVP(measured_);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace gtsam */
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* 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 testDistanceFactor.cpp
|
||||
* @brief Unit tests for DistanceFactor Class
|
||||
* @author Duy-Nguyen Ta
|
||||
* @date Oct 2012
|
||||
*/
|
||||
|
||||
#include <CppUnitLite/TestHarness.h>
|
||||
#include <gtsam/base/TestableAssertions.h>
|
||||
#include <gtsam/base/numericalDerivative.h>
|
||||
#include <gtsam/geometry/Point2.h>
|
||||
#include <gtsam/geometry/Point3.h>
|
||||
#include <gtsam/slam/DistanceFactor.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace gtsam;
|
||||
|
||||
typedef DistanceFactor<Point2> DistanceFactor2D;
|
||||
typedef DistanceFactor<Point3> DistanceFactor3D;
|
||||
|
||||
SharedDiagonal noise = noiseModel::Unit::Create(1);
|
||||
Point3 P(0., 1., 2.5), Q(10., -81., 7.);
|
||||
Point2 p(1., 2.5), q(-81., 7.);
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST(DistanceFactor, Point3) {
|
||||
DistanceFactor3D distanceFactor(0, 1, P.distance(Q), noise);
|
||||
Matrix H1, H2;
|
||||
Vector error = distanceFactor.evaluateError(P, Q, H1, H2);
|
||||
|
||||
Vector expectedError = zero(1);
|
||||
EXPECT(assert_equal(expectedError, error, 1e-10));
|
||||
|
||||
boost::function<Vector(const Point3&, const Point3&)> testEvaluateError(
|
||||
boost::bind(&DistanceFactor3D::evaluateError, distanceFactor, _1, _2,
|
||||
boost::none, boost::none));
|
||||
Matrix numericalH1 = numericalDerivative21(testEvaluateError, P, Q, 1e-5);
|
||||
Matrix numericalH2 = numericalDerivative22(testEvaluateError, P, Q, 1e-5);
|
||||
|
||||
EXPECT(assert_equal(numericalH1, H1, 1e-8));
|
||||
EXPECT(assert_equal(numericalH2, H2, 1e-8));
|
||||
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST(DistanceFactor, Point2) {
|
||||
DistanceFactor2D distanceFactor(0, 1, p.distance(q), noise);
|
||||
Matrix H1, H2;
|
||||
Vector error = distanceFactor.evaluateError(p, q, H1, H2);
|
||||
|
||||
Vector expectedError = zero(1);
|
||||
EXPECT(assert_equal(expectedError, error, 1e-10));
|
||||
|
||||
boost::function<Vector(const Point2&, const Point2&)> testEvaluateError(
|
||||
boost::bind(&DistanceFactor2D::evaluateError, distanceFactor, _1, _2,
|
||||
boost::none, boost::none));
|
||||
Matrix numericalH1 = numericalDerivative21(testEvaluateError, p, q, 1e-5);
|
||||
Matrix numericalH2 = numericalDerivative22(testEvaluateError, p, q, 1e-5);
|
||||
|
||||
EXPECT(assert_equal(numericalH1, H1, 1e-8));
|
||||
EXPECT(assert_equal(numericalH2, H2, 1e-8));
|
||||
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
int main() {
|
||||
TestResult tr;
|
||||
return TestRegistry::runAllTests(tr);
|
||||
}
|
||||
/* ************************************************************************* */
|
||||
|
||||
Loading…
Reference in New Issue