Removed 2 more ordered files
							parent
							
								
									667facdbce
								
							
						
					
					
						commit
						4db55a3a6a
					
				|  | @ -1,651 +0,0 @@ | |||
| /* ----------------------------------------------------------------------------
 | ||||
| 
 | ||||
|  * 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    smallExample.h | ||||
|  * @brief   Create small example with two poses and one landmark | ||||
|  * @brief   smallExample | ||||
|  * @author  Carlos Nieto | ||||
|  */ | ||||
| 
 | ||||
| // \callgraph
 | ||||
| 
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <tests/simulated2D.h> | ||||
| #include <gtsam/nonlinear/Symbol.h> | ||||
| #include <gtsam/nonlinear/NonlinearFactorGraph.h> | ||||
| #include <boost/tuple/tuple.hpp> | ||||
| 
 | ||||
| namespace gtsam { | ||||
| namespace example { | ||||
|   namespace { | ||||
| 
 | ||||
| typedef NonlinearFactorGraph Graph; | ||||
| 
 | ||||
| /**
 | ||||
|  * Create small example for non-linear factor graph | ||||
|  */ | ||||
| boost::shared_ptr<const Graph> sharedNonlinearFactorGraph(); | ||||
| Graph createNonlinearFactorGraph(); | ||||
| 
 | ||||
| /**
 | ||||
|  * Create values structure to go with it | ||||
|  * The ground truth values structure for the example above | ||||
|  */ | ||||
| Values createValues(); | ||||
| 
 | ||||
| /** Vector Values equivalent */ | ||||
| VectorValuesOrdered createVectorValues(); | ||||
| 
 | ||||
| /**
 | ||||
|  * create a noisy values structure for a nonlinear factor graph | ||||
|  */ | ||||
| boost::shared_ptr<const Values> sharedNoisyValues(); | ||||
| Values createNoisyValues(); | ||||
| 
 | ||||
| /**
 | ||||
|  * Zero delta config | ||||
|  */ | ||||
| VectorValuesOrdered createZeroDelta(const OrderingOrdered& ordering); | ||||
| 
 | ||||
| /**
 | ||||
|  * Delta config that, when added to noisyValues, returns the ground truth | ||||
|  */ | ||||
| VectorValuesOrdered createCorrectDelta(const OrderingOrdered& ordering); | ||||
| 
 | ||||
| /**
 | ||||
|  * create a linear factor graph | ||||
|  * The non-linear graph above evaluated at NoisyValues | ||||
|  */ | ||||
| GaussianFactorGraphOrdered createGaussianFactorGraph(const OrderingOrdered& ordering); | ||||
| 
 | ||||
| /**
 | ||||
|  * create small Chordal Bayes Net x <- y | ||||
|  */ | ||||
| GaussianBayesNetOrdered createSmallGaussianBayesNet(); | ||||
| 
 | ||||
| /**
 | ||||
|  * Create really non-linear factor graph (cos/sin) | ||||
|  */ | ||||
| boost::shared_ptr<const Graph> | ||||
| sharedReallyNonlinearFactorGraph(); | ||||
| Graph createReallyNonlinearFactorGraph(); | ||||
| 
 | ||||
| /**
 | ||||
|  * Create a full nonlinear smoother | ||||
|  * @param T number of time-steps | ||||
|  */ | ||||
| std::pair<Graph, Values> createNonlinearSmoother(int T); | ||||
| 
 | ||||
| /**
 | ||||
|  * Create a Kalman smoother by linearizing a non-linear factor graph | ||||
|  * @param T number of time-steps | ||||
|  */ | ||||
| std::pair<FactorGraphOrdered<GaussianFactorOrdered>, OrderingOrdered> createSmoother(int T, boost::optional<OrderingOrdered> ordering = boost::none); | ||||
| 
 | ||||
| /* ******************************************************* */ | ||||
| // Linear Constrained Examples
 | ||||
| /* ******************************************************* */ | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a simple constrained graph with one linear factor and | ||||
|  * one binary equality constraint that sets x = y | ||||
|  */ | ||||
| GaussianFactorGraphOrdered createSimpleConstraintGraph(); | ||||
| VectorValuesOrdered createSimpleConstraintValues(); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a simple constrained graph with one linear factor and | ||||
|  * one binary constraint. | ||||
|  */ | ||||
| GaussianFactorGraphOrdered createSingleConstraintGraph(); | ||||
| VectorValuesOrdered createSingleConstraintValues(); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a constrained graph with a linear factor and two | ||||
|  * binary constraints that share a node | ||||
|  */ | ||||
| GaussianFactorGraphOrdered createMultiConstraintGraph(); | ||||
| VectorValuesOrdered createMultiConstraintValues(); | ||||
| 
 | ||||
| /* ******************************************************* */ | ||||
| // Planar graph with easy subtree for SubgraphPreconditioner
 | ||||
| /* ******************************************************* */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Create factor graph with N^2 nodes, for example for N=3 | ||||
|  *  x13-x23-x33 | ||||
|  *   |   |   | | ||||
|  *  x12-x22-x32 | ||||
|  *   |   |   | | ||||
|  * -x11-x21-x31 | ||||
|  * with x11 clamped at (1,1), and others related by 2D odometry. | ||||
|  */ | ||||
| boost::tuple<GaussianFactorGraphOrdered, VectorValuesOrdered> planarGraph(size_t N); | ||||
| 
 | ||||
| /*
 | ||||
|  * Create canonical ordering for planar graph that also works for tree | ||||
|  * With x11 the root, e.g. for N=3 | ||||
|  * x33 x23 x13 x32 x22 x12 x31 x21 x11 | ||||
|  */ | ||||
| OrderingOrdered planarOrdering(size_t N); | ||||
| 
 | ||||
| /*
 | ||||
|  * Split graph into tree and loop closing constraints, e.g., with N=3 | ||||
|  *  x13-x23-x33 | ||||
|  *   | | ||||
|  *  x12-x22-x32 | ||||
|  *   | | ||||
|  * -x11-x21-x31 | ||||
|  */ | ||||
| std::pair<GaussianFactorGraphOrdered, GaussianFactorGraphOrdered > splitOffPlanarTree( | ||||
|     size_t N, const GaussianFactorGraphOrdered& original); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // Implementations
 | ||||
| 
 | ||||
| //  using namespace gtsam::noiseModel;
 | ||||
| 
 | ||||
| namespace impl { | ||||
| typedef boost::shared_ptr<NonlinearFactor> shared_nlf; | ||||
| 
 | ||||
| static SharedDiagonal sigma1_0 = noiseModel::Isotropic::Sigma(2,1.0); | ||||
| static SharedDiagonal sigma0_1 = noiseModel::Isotropic::Sigma(2,0.1); | ||||
| static SharedDiagonal sigma0_2 = noiseModel::Isotropic::Sigma(2,0.2); | ||||
| static SharedDiagonal constraintModel = noiseModel::Constrained::All(2); | ||||
| 
 | ||||
| static const Index _l1_=0, _x1_=1, _x2_=2; | ||||
| static const Index _x_=0, _y_=1, _z_=2; | ||||
| } // \namespace impl
 | ||||
| 
 | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| boost::shared_ptr<const Graph> sharedNonlinearFactorGraph() { | ||||
|   using namespace impl; | ||||
|   using symbol_shorthand::X; | ||||
|   using symbol_shorthand::L; | ||||
|   // Create
 | ||||
|   boost::shared_ptr<Graph> nlfg( | ||||
|       new Graph); | ||||
| 
 | ||||
|   // prior on x1
 | ||||
|   Point2 mu; | ||||
|   shared_nlf f1(new simulated2D::Prior(mu, sigma0_1, X(1))); | ||||
|   nlfg->push_back(f1); | ||||
| 
 | ||||
|   // odometry between x1 and x2
 | ||||
|   Point2 z2(1.5, 0); | ||||
|   shared_nlf f2(new simulated2D::Odometry(z2, sigma0_1, X(1), X(2))); | ||||
|   nlfg->push_back(f2); | ||||
| 
 | ||||
|   // measurement between x1 and l1
 | ||||
|   Point2 z3(0, -1); | ||||
|   shared_nlf f3(new simulated2D::Measurement(z3, sigma0_2, X(1), L(1))); | ||||
|   nlfg->push_back(f3); | ||||
| 
 | ||||
|   // measurement between x2 and l1
 | ||||
|   Point2 z4(-1.5, -1.); | ||||
|   shared_nlf f4(new simulated2D::Measurement(z4, sigma0_2, X(2), L(1))); | ||||
|   nlfg->push_back(f4); | ||||
| 
 | ||||
|   return nlfg; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| Graph createNonlinearFactorGraph() { | ||||
|   return *sharedNonlinearFactorGraph(); | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| Values createValues() { | ||||
|   using symbol_shorthand::X; | ||||
|   using symbol_shorthand::L; | ||||
|   Values c; | ||||
|   c.insert(X(1), Point2(0.0, 0.0)); | ||||
|   c.insert(X(2), Point2(1.5, 0.0)); | ||||
|   c.insert(L(1), Point2(0.0, -1.0)); | ||||
|   return c; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| VectorValuesOrdered createVectorValues() { | ||||
|   using namespace impl; | ||||
|   VectorValuesOrdered c(std::vector<size_t>(3, 2)); | ||||
|   c[_l1_] = Vector_(2, 0.0, -1.0); | ||||
|   c[_x1_] = Vector_(2, 0.0, 0.0); | ||||
|   c[_x2_] = Vector_(2, 1.5, 0.0); | ||||
|   return c; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| boost::shared_ptr<const Values> sharedNoisyValues() { | ||||
|   using symbol_shorthand::X; | ||||
|   using symbol_shorthand::L; | ||||
|   boost::shared_ptr<Values> c(new Values); | ||||
|   c->insert(X(1), Point2(0.1, 0.1)); | ||||
|   c->insert(X(2), Point2(1.4, 0.2)); | ||||
|   c->insert(L(1), Point2(0.1, -1.1)); | ||||
|   return c; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| Values createNoisyValues() { | ||||
|   return *sharedNoisyValues(); | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| VectorValuesOrdered createCorrectDelta(const OrderingOrdered& ordering) { | ||||
|   using symbol_shorthand::X; | ||||
|   using symbol_shorthand::L; | ||||
|   VectorValuesOrdered c(std::vector<size_t>(3,2)); | ||||
|   c[ordering[L(1)]] = Vector_(2, -0.1, 0.1); | ||||
|   c[ordering[X(1)]] = Vector_(2, -0.1, -0.1); | ||||
|   c[ordering[X(2)]] = Vector_(2, 0.1, -0.2); | ||||
|   return c; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| VectorValuesOrdered createZeroDelta(const OrderingOrdered& ordering) { | ||||
|   using symbol_shorthand::X; | ||||
|   using symbol_shorthand::L; | ||||
|   VectorValuesOrdered c(std::vector<size_t>(3,2)); | ||||
|   c[ordering[L(1)]] = zero(2); | ||||
|   c[ordering[X(1)]] = zero(2); | ||||
|   c[ordering[X(2)]] = zero(2); | ||||
|   return c; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| GaussianFactorGraphOrdered createGaussianFactorGraph(const OrderingOrdered& ordering) { | ||||
|   using symbol_shorthand::X; | ||||
|   using symbol_shorthand::L; | ||||
|   // Create empty graph
 | ||||
|   GaussianFactorGraphOrdered fg; | ||||
| 
 | ||||
|   SharedDiagonal unit2 = noiseModel::Unit::Create(2); | ||||
| 
 | ||||
|   // linearized prior on x1: c[_x1_]+x1=0 i.e. x1=-c[_x1_]
 | ||||
|   fg.push_back(boost::make_shared<JacobianFactorOrdered>(ordering[X(1)], 10*eye(2), -1.0*ones(2), unit2)); | ||||
| 
 | ||||
|   // odometry between x1 and x2: x2-x1=[0.2;-0.1]
 | ||||
|   fg.push_back(boost::make_shared<JacobianFactorOrdered>(ordering[X(1)], -10*eye(2),ordering[X(2)], 10*eye(2), Vector_(2, 2.0, -1.0), unit2)); | ||||
| 
 | ||||
|   // measurement between x1 and l1: l1-x1=[0.0;0.2]
 | ||||
|   fg.push_back(boost::make_shared<JacobianFactorOrdered>(ordering[X(1)], -5*eye(2), ordering[L(1)], 5*eye(2), Vector_(2, 0.0, 1.0), unit2)); | ||||
| 
 | ||||
|   // measurement between x2 and l1: l1-x2=[-0.2;0.3]
 | ||||
|   fg.push_back(boost::make_shared<JacobianFactorOrdered>(ordering[X(2)], -5*eye(2), ordering[L(1)], 5*eye(2), Vector_(2, -1.0, 1.5), unit2)); | ||||
| 
 | ||||
|   return fg; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| /** create small Chordal Bayes Net x <- y
 | ||||
|  * x y d | ||||
|  * 1 1 9 | ||||
|  *   1 5 | ||||
|  */ | ||||
| GaussianBayesNetOrdered createSmallGaussianBayesNet() { | ||||
|   using namespace impl; | ||||
|   Matrix R11 = Matrix_(1, 1, 1.0), S12 = Matrix_(1, 1, 1.0); | ||||
|   Matrix R22 = Matrix_(1, 1, 1.0); | ||||
|   Vector d1(1), d2(1); | ||||
|   d1(0) = 9; | ||||
|   d2(0) = 5; | ||||
|   Vector tau(1); | ||||
|   tau(0) = 1.0; | ||||
| 
 | ||||
|   // define nodes and specify in reverse topological sort (i.e. parents last)
 | ||||
|   GaussianConditionalOrdered::shared_ptr Px_y(new GaussianConditionalOrdered(_x_, d1, R11, _y_, S12, tau)); | ||||
|   GaussianConditionalOrdered::shared_ptr Py(new GaussianConditionalOrdered(_y_, d2, R22, tau)); | ||||
|   GaussianBayesNetOrdered cbn; | ||||
|   cbn.push_back(Px_y); | ||||
|   cbn.push_back(Py); | ||||
| 
 | ||||
|   return cbn; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| // Some nonlinear functions to optimize
 | ||||
| /* ************************************************************************* */ | ||||
| namespace smallOptimize { | ||||
| 
 | ||||
| Point2 h(const Point2& v) { | ||||
|   return Point2(cos(v.x()), sin(v.y())); | ||||
| } | ||||
| 
 | ||||
| Matrix H(const Point2& v) { | ||||
|   return Matrix_(2, 2, | ||||
|       -sin(v.x()), 0.0, | ||||
|       0.0, cos(v.y())); | ||||
| } | ||||
| 
 | ||||
| struct UnaryFactor: public gtsam::NoiseModelFactor1<Point2> { | ||||
| 
 | ||||
|   Point2 z_; | ||||
| 
 | ||||
|   UnaryFactor(const Point2& z, const SharedNoiseModel& model, Key key) : | ||||
|     gtsam::NoiseModelFactor1<Point2>(model, key), z_(z) { | ||||
|   } | ||||
| 
 | ||||
|   Vector evaluateError(const Point2& x, boost::optional<Matrix&> A = boost::none) const { | ||||
|     if (A) *A = H(x); | ||||
|     return (h(x) - z_).vector(); | ||||
|   } | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| boost::shared_ptr<const Graph> sharedReallyNonlinearFactorGraph() { | ||||
|   using symbol_shorthand::X; | ||||
|   using symbol_shorthand::L; | ||||
|   boost::shared_ptr<Graph> fg(new Graph); | ||||
|   Vector z = Vector_(2, 1.0, 0.0); | ||||
|   double sigma = 0.1; | ||||
|   boost::shared_ptr<smallOptimize::UnaryFactor> factor( | ||||
|       new smallOptimize::UnaryFactor(z, noiseModel::Isotropic::Sigma(2,sigma), X(1))); | ||||
|   fg->push_back(factor); | ||||
|   return fg; | ||||
| } | ||||
| 
 | ||||
| Graph createReallyNonlinearFactorGraph() { | ||||
|   return *sharedReallyNonlinearFactorGraph(); | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| std::pair<Graph, Values> createNonlinearSmoother(int T) { | ||||
|   using namespace impl; | ||||
|   using symbol_shorthand::X; | ||||
|   using symbol_shorthand::L; | ||||
| 
 | ||||
|   // Create
 | ||||
|   Graph nlfg; | ||||
|   Values poses; | ||||
| 
 | ||||
|   // prior on x1
 | ||||
|   Point2 x1(1.0, 0.0); | ||||
|   shared_nlf prior(new simulated2D::Prior(x1, sigma1_0, X(1))); | ||||
|   nlfg.push_back(prior); | ||||
|   poses.insert(X(1), x1); | ||||
| 
 | ||||
|   for (int t = 2; t <= T; t++) { | ||||
|     // odometry between x_t and x_{t-1}
 | ||||
|     Point2 odo(1.0, 0.0); | ||||
|     shared_nlf odometry(new simulated2D::Odometry(odo, sigma1_0, X(t - 1), X(t))); | ||||
|     nlfg.push_back(odometry); | ||||
| 
 | ||||
|     // measurement on x_t is like perfect GPS
 | ||||
|     Point2 xt(t, 0); | ||||
|     shared_nlf measurement(new simulated2D::Prior(xt, sigma1_0, X(t))); | ||||
|     nlfg.push_back(measurement); | ||||
| 
 | ||||
|     // initial estimate
 | ||||
|     poses.insert(X(t), xt); | ||||
|   } | ||||
| 
 | ||||
|   return std::make_pair(nlfg, poses); | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| std::pair<FactorGraphOrdered<GaussianFactorOrdered>, OrderingOrdered> createSmoother(int T, boost::optional<OrderingOrdered> ordering) { | ||||
|   Graph nlfg; | ||||
|   Values poses; | ||||
|   boost::tie(nlfg, poses) = createNonlinearSmoother(T); | ||||
| 
 | ||||
|   if(!ordering) ordering = *poses.orderingArbitrary(); | ||||
|   return std::make_pair(*nlfg.linearize(poses, *ordering), *ordering); | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| GaussianFactorGraphOrdered createSimpleConstraintGraph() { | ||||
|   using namespace impl; | ||||
|   // create unary factor
 | ||||
|   // prior on _x_, mean = [1,-1], sigma=0.1
 | ||||
|   Matrix Ax = eye(2); | ||||
|   Vector b1(2); | ||||
|   b1(0) = 1.0; | ||||
|   b1(1) = -1.0; | ||||
|   JacobianFactorOrdered::shared_ptr f1(new JacobianFactorOrdered(_x_, Ax, b1, sigma0_1)); | ||||
| 
 | ||||
|   // create binary constraint factor
 | ||||
|   // between _x_ and _y_, that is going to be the only factor on _y_
 | ||||
|   // |1 0||x_1| + |-1  0||y_1| = |0|
 | ||||
|   // |0 1||x_2|   | 0 -1||y_2|   |0|
 | ||||
|   Matrix Ax1 = eye(2); | ||||
|   Matrix Ay1 = eye(2) * -1; | ||||
|   Vector b2 = Vector_(2, 0.0, 0.0); | ||||
|   JacobianFactorOrdered::shared_ptr f2(new JacobianFactorOrdered(_x_, Ax1, _y_, Ay1, b2, | ||||
|       constraintModel)); | ||||
| 
 | ||||
|   // construct the graph
 | ||||
|   GaussianFactorGraphOrdered fg; | ||||
|   fg.push_back(f1); | ||||
|   fg.push_back(f2); | ||||
| 
 | ||||
|   return fg; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| VectorValuesOrdered createSimpleConstraintValues() { | ||||
|   using namespace impl; | ||||
|   using symbol_shorthand::X; | ||||
|   using symbol_shorthand::L; | ||||
|   VectorValuesOrdered config(std::vector<size_t>(2,2)); | ||||
|   Vector v = Vector_(2, 1.0, -1.0); | ||||
|   config[_x_] = v; | ||||
|   config[_y_] = v; | ||||
|   return config; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| GaussianFactorGraphOrdered createSingleConstraintGraph() { | ||||
|   using namespace impl; | ||||
|   // create unary factor
 | ||||
|   // prior on _x_, mean = [1,-1], sigma=0.1
 | ||||
|   Matrix Ax = eye(2); | ||||
|   Vector b1(2); | ||||
|   b1(0) = 1.0; | ||||
|   b1(1) = -1.0; | ||||
|   //GaussianFactorOrdered::shared_ptr f1(new JacobianFactor(_x_, sigma0_1->Whiten(Ax), sigma0_1->whiten(b1), sigma0_1));
 | ||||
|   JacobianFactorOrdered::shared_ptr f1(new JacobianFactorOrdered(_x_, Ax, b1, sigma0_1)); | ||||
| 
 | ||||
|   // create binary constraint factor
 | ||||
|   // between _x_ and _y_, that is going to be the only factor on _y_
 | ||||
|   // |1 2||x_1| + |10 0||y_1| = |1|
 | ||||
|   // |2 1||x_2|   |0 10||y_2|   |2|
 | ||||
|   Matrix Ax1(2, 2); | ||||
|   Ax1(0, 0) = 1.0; | ||||
|   Ax1(0, 1) = 2.0; | ||||
|   Ax1(1, 0) = 2.0; | ||||
|   Ax1(1, 1) = 1.0; | ||||
|   Matrix Ay1 = eye(2) * 10; | ||||
|   Vector b2 = Vector_(2, 1.0, 2.0); | ||||
|   JacobianFactorOrdered::shared_ptr f2(new JacobianFactorOrdered(_x_, Ax1, _y_, Ay1, b2, | ||||
|       constraintModel)); | ||||
| 
 | ||||
|   // construct the graph
 | ||||
|   GaussianFactorGraphOrdered fg; | ||||
|   fg.push_back(f1); | ||||
|   fg.push_back(f2); | ||||
| 
 | ||||
|   return fg; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| VectorValuesOrdered createSingleConstraintValues() { | ||||
|   using namespace impl; | ||||
|   VectorValuesOrdered config(std::vector<size_t>(2,2)); | ||||
|   config[_x_] = Vector_(2, 1.0, -1.0); | ||||
|   config[_y_] = Vector_(2, 0.2, 0.1); | ||||
|   return config; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| GaussianFactorGraphOrdered createMultiConstraintGraph() { | ||||
|   using namespace impl; | ||||
|   // unary factor 1
 | ||||
|   Matrix A = eye(2); | ||||
|   Vector b = Vector_(2, -2.0, 2.0); | ||||
|   JacobianFactorOrdered::shared_ptr lf1(new JacobianFactorOrdered(_x_, A, b, sigma0_1)); | ||||
| 
 | ||||
|   // constraint 1
 | ||||
|   Matrix A11(2, 2); | ||||
|   A11(0, 0) = 1.0; | ||||
|   A11(0, 1) = 2.0; | ||||
|   A11(1, 0) = 2.0; | ||||
|   A11(1, 1) = 1.0; | ||||
| 
 | ||||
|   Matrix A12(2, 2); | ||||
|   A12(0, 0) = 10.0; | ||||
|   A12(0, 1) = 0.0; | ||||
|   A12(1, 0) = 0.0; | ||||
|   A12(1, 1) = 10.0; | ||||
| 
 | ||||
|   Vector b1(2); | ||||
|   b1(0) = 1.0; | ||||
|   b1(1) = 2.0; | ||||
|   JacobianFactorOrdered::shared_ptr lc1(new JacobianFactorOrdered(_x_, A11, _y_, A12, b1, | ||||
|       constraintModel)); | ||||
| 
 | ||||
|   // constraint 2
 | ||||
|   Matrix A21(2, 2); | ||||
|   A21(0, 0) = 3.0; | ||||
|   A21(0, 1) = 4.0; | ||||
|   A21(1, 0) = -1.0; | ||||
|   A21(1, 1) = -2.0; | ||||
| 
 | ||||
|   Matrix A22(2, 2); | ||||
|   A22(0, 0) = 1.0; | ||||
|   A22(0, 1) = 1.0; | ||||
|   A22(1, 0) = 1.0; | ||||
|   A22(1, 1) = 2.0; | ||||
| 
 | ||||
|   Vector b2(2); | ||||
|   b2(0) = 3.0; | ||||
|   b2(1) = 4.0; | ||||
|   JacobianFactorOrdered::shared_ptr lc2(new JacobianFactorOrdered(_x_, A21, _z_, A22, b2, | ||||
|       constraintModel)); | ||||
| 
 | ||||
|   // construct the graph
 | ||||
|   GaussianFactorGraphOrdered fg; | ||||
|   fg.push_back(lf1); | ||||
|   fg.push_back(lc1); | ||||
|   fg.push_back(lc2); | ||||
| 
 | ||||
|   return fg; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| VectorValuesOrdered createMultiConstraintValues() { | ||||
|   using namespace impl; | ||||
|   VectorValuesOrdered config(std::vector<size_t>(3,2)); | ||||
|   config[_x_] = Vector_(2, -2.0, 2.0); | ||||
|   config[_y_] = Vector_(2, -0.1, 0.4); | ||||
|   config[_z_] = Vector_(2, -4.0, 5.0); | ||||
|   return config; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| // Create key for simulated planar graph
 | ||||
| namespace impl { | ||||
| Symbol key(int x, int y) { | ||||
|   using symbol_shorthand::X; | ||||
|   return X(1000*x+y); | ||||
| } | ||||
| } // \namespace impl
 | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| boost::tuple<GaussianFactorGraphOrdered, VectorValuesOrdered> planarGraph(size_t N) { | ||||
|   using namespace impl; | ||||
| 
 | ||||
|   // create empty graph
 | ||||
|   NonlinearFactorGraph nlfg; | ||||
| 
 | ||||
|   // Create almost hard constraint on x11, sigma=0 will work for PCG not for normal
 | ||||
|   shared_nlf constraint(new simulated2D::Prior(Point2(1.0, 1.0), noiseModel::Isotropic::Sigma(2,1e-3), key(1,1))); | ||||
|   nlfg.push_back(constraint); | ||||
| 
 | ||||
|   // Create horizontal constraints, 1...N*(N-1)
 | ||||
|   Point2 z1(1.0, 0.0); // move right
 | ||||
|   for (size_t x = 1; x < N; x++) | ||||
|     for (size_t y = 1; y <= N; y++) { | ||||
|       shared_nlf f(new simulated2D::Odometry(z1, noiseModel::Isotropic::Sigma(2,0.01), key(x, y), key(x + 1, y))); | ||||
|       nlfg.push_back(f); | ||||
|     } | ||||
| 
 | ||||
|   // Create vertical constraints, N*(N-1)+1..2*N*(N-1)
 | ||||
|   Point2 z2(0.0, 1.0); // move up
 | ||||
|   for (size_t x = 1; x <= N; x++) | ||||
|     for (size_t y = 1; y < N; y++) { | ||||
|       shared_nlf f(new simulated2D::Odometry(z2, noiseModel::Isotropic::Sigma(2,0.01), key(x, y), key(x, y + 1))); | ||||
|       nlfg.push_back(f); | ||||
|     } | ||||
| 
 | ||||
|   // Create linearization and ground xtrue config
 | ||||
|   Values zeros; | ||||
|   for (size_t x = 1; x <= N; x++) | ||||
|     for (size_t y = 1; y <= N; y++) | ||||
|       zeros.insert(key(x, y), Point2()); | ||||
|   OrderingOrdered ordering(planarOrdering(N)); | ||||
|   VectorValuesOrdered xtrue(zeros.dims(ordering)); | ||||
|   for (size_t x = 1; x <= N; x++) | ||||
|     for (size_t y = 1; y <= N; y++) | ||||
|       xtrue[ordering[key(x, y)]] = Point2(x,y).vector(); | ||||
| 
 | ||||
|   // linearize around zero
 | ||||
|   boost::shared_ptr<GaussianFactorGraphOrdered> gfg = nlfg.linearize(zeros, ordering); | ||||
|   return boost::make_tuple(*gfg, xtrue); | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| OrderingOrdered planarOrdering(size_t N) { | ||||
|   OrderingOrdered ordering; | ||||
|   for (size_t y = N; y >= 1; y--) | ||||
|     for (size_t x = N; x >= 1; x--) | ||||
|       ordering.push_back(impl::key(x, y)); | ||||
|   return ordering; | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| std::pair<GaussianFactorGraphOrdered, GaussianFactorGraphOrdered > splitOffPlanarTree(size_t N, | ||||
|     const GaussianFactorGraphOrdered& original) { | ||||
|   GaussianFactorGraphOrdered T, C; | ||||
| 
 | ||||
|   // Add the x11 constraint to the tree
 | ||||
|   T.push_back(original[0]); | ||||
| 
 | ||||
|   // Add all horizontal constraints to the tree
 | ||||
|   size_t i = 1; | ||||
|   for (size_t x = 1; x < N; x++) | ||||
|     for (size_t y = 1; y <= N; y++, i++) | ||||
|       T.push_back(original[i]); | ||||
| 
 | ||||
|   // Add first vertical column of constraints to T, others to C
 | ||||
|   for (size_t x = 1; x <= N; x++) | ||||
|     for (size_t y = 1; y < N; y++, i++) | ||||
|       if (x == 1) | ||||
|         T.push_back(original[i]); | ||||
|       else | ||||
|         C.push_back(original[i]); | ||||
| 
 | ||||
|   return std::make_pair(T, C); | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| 
 | ||||
| } // anonymous namespace
 | ||||
| } // \namespace example
 | ||||
| } // \namespace gtsam
 | ||||
|  | @ -1,85 +0,0 @@ | |||
| /* ----------------------------------------------------------------------------
 | ||||
| 
 | ||||
|  * 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    testGaussianISAM.cpp | ||||
|  * @brief   Unit tests for GaussianISAM | ||||
|  * @author  Michael Kaess | ||||
|  */ | ||||
| 
 | ||||
| #include <tests/smallExampleOrdered.h> | ||||
| #include <gtsam/nonlinear/OrderingOrdered.h> | ||||
| #include <gtsam/nonlinear/Symbol.h> | ||||
| #include <gtsam/linear/GaussianBayesNetOrdered.h> | ||||
| #include <gtsam/linear/GaussianISAMOrdered.h> | ||||
| #include <gtsam/linear/GaussianSequentialSolver.h> | ||||
| #include <gtsam/linear/GaussianMultifrontalSolver.h> | ||||
| #include <gtsam/inference/ISAMOrdered.h> | ||||
| #include <gtsam/geometry/Rot2.h> | ||||
| 
 | ||||
| #include <CppUnitLite/TestHarness.h> | ||||
| 
 | ||||
| #include <boost/foreach.hpp> | ||||
| #include <boost/assign/std/list.hpp> // for operator += | ||||
| using namespace boost::assign; | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace gtsam; | ||||
| using namespace example; | ||||
| 
 | ||||
| using symbol_shorthand::X; | ||||
| using symbol_shorthand::L; | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| // Some numbers that should be consistent among all smoother tests
 | ||||
| 
 | ||||
| static const double tol = 1e-4; | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| TEST( ISAMOrdered, iSAM_smoother ) | ||||
| { | ||||
|   OrderingOrdered ordering; | ||||
|   for (int t = 1; t <= 7; t++) ordering += X(t); | ||||
| 
 | ||||
|   // Create smoother with 7 nodes
 | ||||
|   GaussianFactorGraphOrdered smoother = createSmoother(7, ordering).first; | ||||
| 
 | ||||
|   // run iSAM for every factor
 | ||||
|   GaussianISAMOrdered actual; | ||||
|   BOOST_FOREACH(boost::shared_ptr<GaussianFactorOrdered> factor, smoother) { | ||||
|     GaussianFactorGraphOrdered factorGraph; | ||||
|     factorGraph.push_back(factor); | ||||
|     actual.update(factorGraph); | ||||
|   } | ||||
| 
 | ||||
|   // Create expected Bayes Tree by solving smoother with "natural" ordering
 | ||||
|   BayesTreeOrdered<GaussianConditionalOrdered>::shared_ptr bayesTree = GaussianMultifrontalSolver(smoother).eliminate(); | ||||
|   GaussianISAMOrdered expected(*bayesTree); | ||||
| 
 | ||||
|   // Verify sigmas in the bayes tree
 | ||||
|   BOOST_FOREACH(const GaussianBayesTreeOrdered::sharedClique& clique, bayesTree->nodes()) { | ||||
|     GaussianConditionalOrdered::shared_ptr conditional = clique->conditional(); | ||||
|     size_t dim = conditional->dim(); | ||||
|     EXPECT(assert_equal(gtsam::ones(dim), conditional->get_sigmas(), tol)); | ||||
|   } | ||||
| 
 | ||||
|   // Check whether BayesTree is correct
 | ||||
|   EXPECT(assert_equal(expected, actual)); | ||||
| 
 | ||||
|   // obtain solution
 | ||||
|   VectorValuesOrdered e(VectorValuesOrdered::Zero(7,2)); // expected solution
 | ||||
|   VectorValuesOrdered optimized = optimize(actual); // actual solution
 | ||||
|   EXPECT(assert_equal(e, optimized)); | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| int main() { TestResult tr; return TestRegistry::runAllTests(tr);} | ||||
| /* ************************************************************************* */ | ||||
		Loading…
	
		Reference in New Issue