new predict variant predictQ

release/4.3a0
Frank Dellaert 2012-01-18 04:44:16 +00:00
parent a209741e60
commit 035923449b
3 changed files with 72 additions and 7 deletions

View File

@ -311,12 +311,13 @@ class GaussianSequentialSolver {
class KalmanFilter {
KalmanFilter(Vector x0, const SharedDiagonal& P0);
KalmanFilter(Vector x0, const Matrix& P0);
KalmanFilter(Vector x0, Matrix P0);
void print(string s) const;
Vector mean() const;
Matrix information() const;
Matrix covariance() const;
void predict(Matrix F, Matrix B, Vector u, const SharedDiagonal& model);
void predictQ(Matrix F, Matrix B, Vector u, Matrix Q);
void predict2(Matrix A0, Matrix A1, Vector b, const SharedDiagonal& model);
void update(Matrix H, Vector z, const SharedDiagonal& model);
};

View File

@ -104,17 +104,76 @@ namespace gtsam {
density_.reset(solve(factorGraph));
}
/* ************************************************************************* */
void KalmanFilter::predictQ(const Matrix& F, const Matrix& B, const Vector& u,
const Matrix& Q) {
#ifndef NDEBUG
int n = F.cols();
assert(F.rows() == n);
assert(B.rows() == n);
assert(B.cols() == u.size());
assert(Q.rows() == n);
assert(Q.cols() == n);
#endif
// Same scheme as in predict:
GaussianFactorGraph factorGraph;
factorGraph.push_back(density_->toFactor());
// 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
// See documentation in HessianFactor, we have A1 = -F, A2 = I_, b = B*u:
Vector b = B*u;
Matrix M = inverse(Q);
Matrix Ft = trans(F);
Matrix G12 = -Ft*M;
Matrix G11 = -G12*F;
Matrix G22 = M;
Vector g2 = M*b;
Vector g1 = -Ft*g2;
double f = dot(b,g2);
HessianFactor::shared_ptr factor(new HessianFactor(0, 1, G11, G12, g1, G22, g2, f));
//#define DEBUG_PREDICTQ
#ifdef DEBUG_PREDICTQ
gtsam::print(b);
gtsam::print(M);
gtsam::print(G11);
gtsam::print(G12);
gtsam::print(G22);
gtsam::print(g1);
gtsam::print(g2);
cout << f << endl;
factor->print("factor");
#endif
factorGraph.push_back(factor);
// Eliminate graph in order x0, x1, to get Bayes net P(x0|x1)P(x1)
density_.reset(solve(factorGraph));
}
/* ************************************************************************* */
void KalmanFilter::predict2(const Matrix& A0, const Matrix& A1, const Vector& b,
const SharedDiagonal& model) {
// Exactly the same schem as in predict:
// Same scheme as in predict:
GaussianFactorGraph factorGraph;
factorGraph.push_back(density_->toFactor());
// However, now the factor related to the motion model is defined as
// f2(x_{t},x_{t+1}) = |A0*x_{t} + A1*x_{t+1} - b|^2
factorGraph.add(0, A0, 1, A1, b, model);
#ifdef DEBUG_PREDICTQ
gtsam::print(Matrix(trans(A0)*A0));
gtsam::print(Matrix(trans(A0)*A1));
gtsam::print(Matrix(trans(A1)*A1));
gtsam::print(Matrix(trans(A0)*b));
gtsam::print(Matrix(trans(A1)*b));
cout << dot(b,b) << endl;
#endif
density_.reset(solve(factorGraph));
}

View File

@ -83,13 +83,18 @@ namespace gtsam {
* In a linear Kalman Filter, the motion model is f(x_{t}) = F*x_{t} + B*u_{t} + w
* where F is the state transition model/matrix, B is the control input model,
* and w is zero-mean, Gaussian white noise with covariance Q.
* Q is normally derived as G*w*G^T where w models uncertainty of some physical property,
* such as velocity or acceleration, and G is derived from physics.
* In the current implementation, the noise model for w is restricted to a diagonal.
* TODO: allow for a G
*/
void predict(const Matrix& F, const Matrix& B, const Vector& u,
const SharedDiagonal& model);
const SharedDiagonal& modelQ);
/*
* Version of predict with full covariance
* Q is normally derived as G*w*G^T where w models uncertainty of some
* physical property, such as velocity or acceleration, and G is derived from physics.
* This version allows more realistic models than a diagonal covariance matrix.
*/
void predictQ(const Matrix& F, const Matrix& B, const Vector& u,
const Matrix& Q);
/**
* Predict the state P(x_{t+1}|Z^t)