Made KalmanFilter compile
parent
00c1036814
commit
114f389eeb
|
|
@ -20,83 +20,77 @@
|
|||
* @author Frank Dellaert
|
||||
*/
|
||||
|
||||
#include <gtsam/linear/GaussianSequentialSolver.h>
|
||||
#include <gtsam/linear/JacobianFactorOrdered.h>
|
||||
#include <gtsam/linear/KalmanFilter.h>
|
||||
#include <gtsam/linear/HessianFactorOrdered.h>
|
||||
#include <gtsam/inference/PermutationOrdered.h>
|
||||
#include <gtsam/linear/GaussianFactorGraph.h>
|
||||
#include <gtsam/linear/JacobianFactor.h>
|
||||
#include <gtsam/linear/HessianFactor.h>
|
||||
#include <gtsam/base/Testable.h>
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
using namespace boost::assign;
|
||||
using namespace std;
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
using namespace std;
|
||||
|
||||
/// Auxiliary function to solve factor graph and return pointer to root conditional
|
||||
KalmanFilter::State solve(const GaussianFactorGraphOrdered& factorGraph, bool useQR)
|
||||
KalmanFilter::State solve(const GaussianFactorGraph& factorGraph, const GaussianFactorGraph::Eliminate& function)
|
||||
{
|
||||
// Start indices at zero
|
||||
Index nVars = 0;
|
||||
internal::Reduction remapping;
|
||||
BOOST_FOREACH(const GaussianFactorGraphOrdered::sharedFactor& factor, factorGraph)
|
||||
BOOST_FOREACH(Index j, *factor)
|
||||
if(remapping.insert(make_pair(j, nVars)).second)
|
||||
++ nVars;
|
||||
Permutation inverseRemapping = remapping.inverse();
|
||||
GaussianFactorGraphOrdered factorGraphOrdered(factorGraph); // NOTE this shares the factors with the original!!
|
||||
factorGraphOrdered.reduceWithInverse(remapping);
|
||||
// Do a dense solve, e.g. don't use the multifrontal framework
|
||||
// Eliminate the keys in increasing order so that the last key is the one we want to keep.
|
||||
FastSet<Key> keysToEliminate = factorGraph.keys();
|
||||
FastSet<Key>::const_iterator lastKeyPos = keysToEliminate.end();
|
||||
-- lastKeyPos;
|
||||
Key remainingKey = *lastKeyPos;
|
||||
keysToEliminate.erase(lastKeyPos);
|
||||
GaussianFactorGraph::EliminationResult result = function(factorGraph, Ordering(keysToEliminate));
|
||||
|
||||
// Solve the factor graph
|
||||
GaussianSequentialSolver solver(factorGraphOrdered, useQR);
|
||||
GaussianBayesNetOrdered::shared_ptr bayesNet = solver.eliminate();
|
||||
// As this is a filter, all we need is the posterior P(x_t). Eliminate it to be
|
||||
// upper-triangular.
|
||||
GaussianFactorGraph graphOfRemainingFactor;
|
||||
graphOfRemainingFactor += result.second;
|
||||
GaussianDensity::shared_ptr state = boost::make_shared<GaussianDensity>(
|
||||
*function(graphOfRemainingFactor, Ordering(cref_list_of<1>(remainingKey))).first);
|
||||
|
||||
// As this is a filter, all we need is the posterior P(x_t),
|
||||
// so we just keep the root of the Bayes net
|
||||
GaussianConditionalOrdered::shared_ptr conditional = bayesNet->back();
|
||||
|
||||
// Undo the remapping
|
||||
factorGraphOrdered.permuteWithInverse(inverseRemapping);
|
||||
conditional->permuteWithInverse(inverseRemapping);
|
||||
|
||||
// TODO: awful ! A copy constructor followed by ANOTHER copy constructor in make_shared?
|
||||
return boost::make_shared<GaussianDensity>(*conditional);
|
||||
return state;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
KalmanFilter::State fuse(const KalmanFilter::State& p,
|
||||
GaussianFactorOrdered* newFactor, bool useQR) {
|
||||
|
||||
KalmanFilter::State fuse(const KalmanFilter::State& p, GaussianFactor::shared_ptr newFactor,
|
||||
const GaussianFactorGraph::Eliminate& function)
|
||||
{
|
||||
// Create a factor graph
|
||||
GaussianFactorGraphOrdered factorGraph;
|
||||
|
||||
// push back previous solution and new factor
|
||||
factorGraph.push_back(p->toFactor());
|
||||
factorGraph.push_back(GaussianFactorOrdered::shared_ptr(newFactor));
|
||||
GaussianFactorGraph factorGraph;
|
||||
factorGraph += p, newFactor;
|
||||
|
||||
// Eliminate graph in order x0, x1, to get Bayes net P(x0|x1)P(x1)
|
||||
return solve(factorGraph, useQR);
|
||||
return solve(factorGraph, function);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
KalmanFilter::State KalmanFilter::init(const Vector& x0,
|
||||
const SharedDiagonal& P0) {
|
||||
GaussianFactorGraph::Eliminate KalmanFilter::factorization() const {
|
||||
return method_ == QR ?
|
||||
GaussianFactorGraph::Eliminate(EliminateQR) :
|
||||
GaussianFactorGraph::Eliminate(EliminateCholesky);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
KalmanFilter::State KalmanFilter::init(const Vector& x0, const SharedDiagonal& P0) {
|
||||
|
||||
// Create a factor graph f(x0), eliminate it into P(x0)
|
||||
GaussianFactorGraphOrdered factorGraph;
|
||||
factorGraph.add(0, I_, x0, P0); // |x-x0|^2_diagSigma
|
||||
return solve(factorGraph, useQR());
|
||||
GaussianFactorGraph factorGraph;
|
||||
factorGraph += JacobianFactor(0, I_, x0, P0); // |x-x0|^2_diagSigma
|
||||
return solve(factorGraph, factorization());
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
KalmanFilter::State KalmanFilter::init(const Vector& x, const Matrix& P0) {
|
||||
|
||||
// Create a factor graph f(x0), eliminate it into P(x0)
|
||||
GaussianFactorGraphOrdered factorGraph;
|
||||
// 0.5*(x-x0)'*inv(Sigma)*(x-x0)
|
||||
HessianFactorOrdered::shared_ptr factor(new HessianFactorOrdered(0, x, P0));
|
||||
factorGraph.push_back(factor);
|
||||
return solve(factorGraph, useQR());
|
||||
GaussianFactorGraph factorGraph;
|
||||
factorGraph += HessianFactor(0, x, P0); // 0.5*(x-x0)'*inv(Sigma)*(x-x0)
|
||||
return solve(factorGraph, factorization());
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
@ -111,7 +105,7 @@ namespace gtsam {
|
|||
// The factor related to the motion model is defined as
|
||||
// f2(x_{t},x_{t+1}) = (F*x_{t} + B*u - x_{t+1}) * Q^-1 * (F*x_{t} + B*u - x_{t+1})^T
|
||||
Index k = step(p);
|
||||
return fuse(p, new JacobianFactorOrdered(k, -F, k + 1, I_, B * u, model), useQR());
|
||||
return fuse(p, boost::make_shared<JacobianFactor>(k, -F, k + 1, I_, B * u, model), factorization());
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
@ -119,7 +113,7 @@ namespace gtsam {
|
|||
const Matrix& B, const Vector& u, const Matrix& Q) {
|
||||
|
||||
#ifndef NDEBUG
|
||||
int n = F.cols();
|
||||
DenseIndex n = F.cols();
|
||||
assert(F.rows() == n);
|
||||
assert(B.rows() == n);
|
||||
assert(B.cols() == u.size());
|
||||
|
|
@ -136,8 +130,7 @@ namespace gtsam {
|
|||
Vector b = B * u, g2 = M * b, g1 = -Ft * g2;
|
||||
double f = dot(b, g2);
|
||||
Index k = step(p);
|
||||
return fuse(p, new HessianFactorOrdered(k, k + 1, G11, G12, g1, G22, g2, f),
|
||||
useQR());
|
||||
return fuse(p, boost::make_shared<HessianFactor>(k, k + 1, G11, G12, g1, G22, g2, f), factorization());
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
@ -146,7 +139,7 @@ namespace gtsam {
|
|||
// Nhe factor related to the motion model is defined as
|
||||
// f2(x_{t},x_{t+1}) = |A0*x_{t} + A1*x_{t+1} - b|^2
|
||||
Index k = step(p);
|
||||
return fuse(p, new JacobianFactorOrdered(k, A0, k + 1, A1, b, model), useQR());
|
||||
return fuse(p, boost::make_shared<JacobianFactor>(k, A0, k + 1, A1, b, model), factorization());
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
@ -156,7 +149,7 @@ namespace gtsam {
|
|||
// f2 = (h(x_{t}) - z_{t}) * R^-1 * (h(x_{t}) - z_{t})^T
|
||||
// = (x_{t} - z_{t}) * R^-1 * (x_{t} - z_{t})^T
|
||||
Index k = step(p);
|
||||
return fuse(p, new JacobianFactorOrdered(k, H, z, model), useQR());
|
||||
return fuse(p, boost::make_shared<JacobianFactor>(k, H, z, model), factorization());
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
@ -167,7 +160,7 @@ namespace gtsam {
|
|||
Matrix G = Ht * M * H;
|
||||
Vector g = Ht * M * z;
|
||||
double f = dot(z, M * z);
|
||||
return fuse(p, new HessianFactorOrdered(k, G, g, f), useQR());
|
||||
return fuse(p, boost::make_shared<HessianFactor>(k, G, g, f), factorization());
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <gtsam/linear/GaussianDensity.h>
|
||||
#include <gtsam/linear/GaussianFactorGraph.h>
|
||||
#include <gtsam/linear/NoiseModel.h>
|
||||
|
||||
#ifndef KALMANFILTER_DEFAULT_FACTORIZATION
|
||||
|
|
@ -60,9 +61,7 @@ namespace gtsam {
|
|||
const Matrix I_; /** identity matrix of size n*n */
|
||||
const Factorization method_; /** algorithm */
|
||||
|
||||
bool useQR() const {
|
||||
return method_ == QR;
|
||||
}
|
||||
GaussianFactorGraph::Eliminate factorization() const;
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue