gtsam/gtsam_unstable/slam/TSAMFactors.h

170 lines
5.0 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 TSAMFactors.h
* @brief TSAM 1 Factors, simpler than the hierarchical TSAM 2
* @author Frank Dellaert
* @date May 2014
*/
#pragma once
#include <gtsam/geometry/Pose2.h>
#include <gtsam/nonlinear/NonlinearFactor.h>
namespace gtsam {
/**
* DeltaFactor: relative 2D measurement between Pose2 and Point2
*/
class DeltaFactor: public NoiseModelFactorN<Pose2, Point2> {
public:
typedef DeltaFactor This;
typedef NoiseModelFactorN<Pose2, Point2> Base;
typedef std::shared_ptr<This> shared_ptr;
private:
Point2 measured_; ///< the measurement
public:
// Provide access to the Matrix& version of evaluateError:
using Base::evaluateError;
/// Constructor
DeltaFactor(Key i, Key j, const Point2& measured,
const SharedNoiseModel& model) :
Base(model, i, j), measured_(measured) {
}
/// Evaluate measurement error h(x)-z
Vector evaluateError(const Pose2& pose, const Point2& point,
OptionalMatrixType H1, OptionalMatrixType H2) const override {
return pose.transformTo(point, H1, H2) - measured_;
}
};
/**
* DeltaFactorBase: relative 2D measurement between Pose2 and Point2, with Basenodes
*/
class DeltaFactorBase: public NoiseModelFactorN<Pose2, Pose2, Pose2, Point2> {
public:
typedef DeltaFactorBase This;
typedef NoiseModelFactorN<Pose2, Pose2, Pose2, Point2> Base;
typedef std::shared_ptr<This> shared_ptr;
private:
Point2 measured_; ///< the measurement
public:
// Provide access to the Matrix& version of evaluateError:
using Base::evaluateError;
/// Constructor
DeltaFactorBase(Key b1, Key i, Key b2, Key j, const Point2& measured,
const SharedNoiseModel& model) :
Base(model, b1, i, b2, j), measured_(measured) {
}
/// Evaluate measurement error h(x)-z
Vector evaluateError(const Pose2& base1, const Pose2& pose,
const Pose2& base2, const Point2& point, //
OptionalMatrixType H1, OptionalMatrixType H2, //
OptionalMatrixType H3, OptionalMatrixType H4) const override {
if (H1 || H2 || H3 || H4) {
// TODO use fixed-size matrices
Matrix D_pose_g_base1, D_pose_g_pose;
Pose2 pose_g = base1.compose(pose, D_pose_g_base1, D_pose_g_pose);
Matrix D_point_g_base2, D_point_g_point;
Point2 point_g = base2.transformFrom(point, D_point_g_base2,
D_point_g_point);
Matrix D_e_pose_g, D_e_point_g;
Point2 d = pose_g.transformTo(point_g, D_e_pose_g, D_e_point_g);
if (H1)
*H1 = D_e_pose_g * D_pose_g_base1;
if (H2)
*H2 = D_e_pose_g * D_pose_g_pose;
if (H3)
*H3 = D_e_point_g * D_point_g_base2;
if (H4)
*H4 = D_e_point_g * D_point_g_point;
return d - measured_;
} else {
Pose2 pose_g = base1.compose(pose);
Point2 point_g = base2.transformFrom(point);
Point2 d = pose_g.transformTo(point_g);
return d - measured_;
}
}
};
/**
* OdometryFactorBase: Pose2 odometry, with Basenodes
*/
class OdometryFactorBase: public NoiseModelFactorN<Pose2, Pose2, Pose2, Pose2> {
public:
typedef OdometryFactorBase This;
typedef NoiseModelFactorN<Pose2, Pose2, Pose2, Pose2> Base;
typedef std::shared_ptr<This> shared_ptr;
private:
Pose2 measured_; ///< the measurement
public:
// Provide access to the Matrix& version of evaluateError:
using Base::evaluateError;
/// Constructor
OdometryFactorBase(Key b1, Key i, Key b2, Key j, const Pose2& measured,
const SharedNoiseModel& model) :
Base(model, b1, i, b2, j), measured_(measured) {
}
/// Evaluate measurement error h(x)-z
Vector evaluateError(const Pose2& base1, const Pose2& pose1,
const Pose2& base2, const Pose2& pose2,
OptionalMatrixType H1, OptionalMatrixType H2,
OptionalMatrixType H3, OptionalMatrixType H4) const override {
if (H1 || H2 || H3 || H4) {
// TODO use fixed-size matrices
Matrix D_pose1_g_base1, D_pose1_g_pose1;
Pose2 pose1_g = base1.compose(pose1, D_pose1_g_base1, D_pose1_g_pose1);
Matrix D_pose2_g_base2, D_pose2_g_pose2;
Pose2 pose2_g = base2.compose(pose2, D_pose2_g_base2, D_pose2_g_pose2);
Matrix D_e_pose1_g, D_e_pose2_g;
Pose2 d = pose1_g.between(pose2_g, D_e_pose1_g, D_e_pose2_g);
if (H1)
*H1 = D_e_pose1_g * D_pose1_g_base1;
if (H2)
*H2 = D_e_pose1_g * D_pose1_g_pose1;
if (H3)
*H3 = D_e_pose2_g * D_pose2_g_base2;
if (H4)
*H4 = D_e_pose2_g * D_pose2_g_pose2;
return measured_.localCoordinates(d);
} else {
Pose2 pose1_g = base1.compose(pose1);
Pose2 pose2_g = base2.compose(pose2);
Pose2 d = pose1_g.between(pose2_g);
return measured_.localCoordinates(d);
}
}
};
}