2014-09-30 18:30:15 +08:00
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
* 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 Expression.h
|
|
|
|
* @date September 18, 2014
|
|
|
|
* @author Frank Dellaert
|
|
|
|
* @author Paul Furgale
|
|
|
|
* @brief Expressions for Block Automatic Differentiation
|
|
|
|
*/
|
|
|
|
|
2014-09-30 18:34:03 +08:00
|
|
|
#include <gtsam_unstable/nonlinear/Expression.h>
|
2014-09-30 18:30:15 +08:00
|
|
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
2014-10-02 17:01:39 +08:00
|
|
|
#include <gtsam/base/Testable.h>
|
2014-09-30 18:30:15 +08:00
|
|
|
|
|
|
|
namespace gtsam {
|
|
|
|
|
|
|
|
/**
|
2014-10-09 19:00:56 +08:00
|
|
|
* Factor that supports arbitrary expressions via AD
|
2014-09-30 18:30:15 +08:00
|
|
|
*/
|
|
|
|
template<class T>
|
2014-10-09 19:00:56 +08:00
|
|
|
class ExpressionFactor: public NoiseModelFactor {
|
2014-09-30 18:30:15 +08:00
|
|
|
|
|
|
|
const T measurement_;
|
|
|
|
const Expression<T> expression_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
/// Constructor
|
2014-10-09 19:00:56 +08:00
|
|
|
ExpressionFactor(const SharedNoiseModel& noiseModel, //
|
2014-10-02 17:01:39 +08:00
|
|
|
const T& measurement, const Expression<T>& expression) :
|
|
|
|
NoiseModelFactor(noiseModel, expression.keys()), //
|
2014-09-30 18:30:15 +08:00
|
|
|
measurement_(measurement), expression_(expression) {
|
|
|
|
}
|
|
|
|
|
2014-10-02 17:01:39 +08:00
|
|
|
/**
|
|
|
|
* Error function *without* the NoiseModel, \f$ z-h(x) \f$.
|
|
|
|
* We override this method to provide
|
|
|
|
* both the function evaluation and its derivative(s) in H.
|
|
|
|
*/
|
|
|
|
virtual Vector unwhitenedError(const Values& x,
|
|
|
|
boost::optional<std::vector<Matrix>&> H = boost::none) const {
|
|
|
|
if (H) {
|
2014-10-02 19:30:16 +08:00
|
|
|
assert(H->size()==size());
|
2014-10-03 16:25:02 +08:00
|
|
|
Augmented<T> augmented = expression_.augmented(x);
|
2014-10-06 18:13:52 +08:00
|
|
|
// move terms to H, which is pre-allocated to correct size
|
2014-10-09 16:58:46 +08:00
|
|
|
augmented.move(*H);
|
2014-10-03 16:25:02 +08:00
|
|
|
return measurement_.localCoordinates(augmented.value());
|
2014-10-02 17:01:39 +08:00
|
|
|
} else {
|
|
|
|
const T& value = expression_.value(x);
|
|
|
|
return measurement_.localCoordinates(value);
|
|
|
|
}
|
2014-09-30 18:30:15 +08:00
|
|
|
}
|
|
|
|
|
2014-10-11 23:05:53 +08:00
|
|
|
virtual boost::shared_ptr<GaussianFactor> linearize(const Values& x) const {
|
|
|
|
|
|
|
|
// Only linearize if the factor is active
|
|
|
|
if (!this->active(x))
|
|
|
|
return boost::shared_ptr<JacobianFactor>();
|
|
|
|
|
|
|
|
// Evaluate error to get Jacobians and RHS vector b
|
|
|
|
Augmented<T> augmented = expression_.augmented(x);
|
|
|
|
Vector b = - measurement_.localCoordinates(augmented.value());
|
|
|
|
// check(noiseModel_, b); // TODO: use, but defined in NonlinearFactor.cpp
|
|
|
|
|
|
|
|
// Whiten the corresponding system now
|
|
|
|
// TODO ! this->noiseModel_->WhitenSystem(A, b);
|
|
|
|
|
|
|
|
// Terms, needed to create JacobianFactor below, are already here!
|
|
|
|
const JacobianMap& terms = augmented.jacobians();
|
|
|
|
|
|
|
|
// TODO pass unwhitened + noise model to Gaussian factor
|
|
|
|
// For now, only linearized constrained factors have noise model at linear level!!!
|
|
|
|
noiseModel::Constrained::shared_ptr constrained = //
|
|
|
|
boost::dynamic_pointer_cast<noiseModel::Constrained>(this->noiseModel_);
|
|
|
|
if (constrained) {
|
2014-10-12 16:52:07 +08:00
|
|
|
return boost::make_shared<JacobianFactor>(terms, b, constrained->unit());
|
2014-10-11 23:05:53 +08:00
|
|
|
} else
|
|
|
|
return boost::make_shared<JacobianFactor>(terms, b);
|
|
|
|
}
|
2014-09-30 18:30:15 +08:00
|
|
|
};
|
2014-10-09 19:00:56 +08:00
|
|
|
// ExpressionFactor
|
2014-09-30 18:30:15 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|