| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @file    testGaussianISAM2.cpp | 
					
						
							|  |  |  |  * @brief   Unit tests for GaussianISAM2 | 
					
						
							|  |  |  |  * @author  Michael Kaess | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <gtsam/base/debug.h>
 | 
					
						
							|  |  |  | #include <gtsam/base/TestableAssertions.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/Ordering.h>
 | 
					
						
							|  |  |  | #include <gtsam/linear/GaussianBayesNet.h>
 | 
					
						
							|  |  |  | #include <gtsam/linear/GaussianSequentialSolver.h>
 | 
					
						
							| 
									
										
										
										
											2012-03-14 03:41:03 +08:00
										 |  |  | #include <gtsam/linear/GaussianBayesTree.h>
 | 
					
						
							| 
									
										
										
										
											2012-06-07 09:24:19 +08:00
										 |  |  | #include <gtsam/linear/JacobianFactorGraph.h>
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  | #include <gtsam/nonlinear/ISAM2.h>
 | 
					
						
							| 
									
										
										
										
											2012-06-10 04:15:44 +08:00
										 |  |  | #include <tests/smallExample.h>
 | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | #include <gtsam/slam/planarSLAM.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  | #include <CppUnitLite/TestHarness.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/foreach.hpp>
 | 
					
						
							|  |  |  | #include <boost/assign/std/list.hpp> // for operator +=
 | 
					
						
							|  |  |  | #include <boost/assign.hpp>
 | 
					
						
							|  |  |  | using namespace boost::assign; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | using namespace std; | 
					
						
							|  |  |  | using namespace gtsam; | 
					
						
							|  |  |  | using boost::shared_ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const double tol = 1e-4; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  | //  SETDEBUG("ISAM2 update", true);
 | 
					
						
							|  |  |  | //  SETDEBUG("ISAM2 update verbose", true);
 | 
					
						
							|  |  |  | //  SETDEBUG("ISAM2 recalculate", true);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Set up parameters
 | 
					
						
							|  |  |  | SharedDiagonal odoNoise = sharedSigmas(Vector_(3, 0.1, 0.1, M_PI/100.0)); | 
					
						
							|  |  |  | SharedDiagonal brNoise = sharedSigmas(Vector_(2, M_PI/100.0, 0.1)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-02 02:54:44 +08:00
										 |  |  | ISAM2 createSlamlikeISAM2( | 
					
						
							|  |  |  | 		boost::optional<Values&> init_values = boost::none, | 
					
						
							|  |  |  | 		boost::optional<planarSLAM::Graph&> full_graph = boost::none, | 
					
						
							|  |  |  | 		const ISAM2Params& params = ISAM2Params(ISAM2GaussNewtonParams(0.001), 0.0, 0, false, true)) { | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // These variables will be reused and accumulate factors and values
 | 
					
						
							| 
									
										
										
										
											2012-05-02 02:54:44 +08:00
										 |  |  |   ISAM2 isam(params); | 
					
						
							|  |  |  | //  ISAM2 isam(ISAM2Params(ISAM2GaussNewtonParams(0.001), 0.0, 0, false, true));
 | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  |   Values fullinit; | 
					
						
							|  |  |  |   planarSLAM::Graph fullgraph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // i keeps track of the time step
 | 
					
						
							|  |  |  |   size_t i = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add a prior at time 0 and update isam
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addPrior(0, Pose2(0.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 0 to time 5
 | 
					
						
							|  |  |  |   for( ; i<5; ++i) { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 5 to 6 and landmark measurement at time 5
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     newfactors.addBearingRange(i, 100, Rot2::fromAngle(M_PI/4.0), 5.0, brNoise); | 
					
						
							|  |  |  |     newfactors.addBearingRange(i, 101, Rot2::fromAngle(-M_PI/4.0), 5.0, brNoise); | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(1.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     init.insert(100, Point2(5.0/sqrt(2.0), 5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     init.insert(101, Point2(5.0/sqrt(2.0), -5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(1.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert(100, Point2(5.0/sqrt(2.0), 5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     fullinit.insert(101, Point2(5.0/sqrt(2.0), -5.0/sqrt(2.0))); | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |     ++ i; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 6 to time 10
 | 
					
						
							|  |  |  |   for( ; i<10; ++i) { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 10 to 11 and landmark measurement at time 10
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     newfactors.addBearingRange(i, 100, Rot2::fromAngle(M_PI/4.0 + M_PI/16.0), 4.5, brNoise); | 
					
						
							|  |  |  |     newfactors.addBearingRange(i, 101, Rot2::fromAngle(-M_PI/4.0 + M_PI/16.0), 4.5, brNoise); | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(6.9, 0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(6.9, 0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |     ++ i; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-02 02:54:44 +08:00
										 |  |  |   if (full_graph) | 
					
						
							|  |  |  |   	*full_graph = fullgraph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (init_values) | 
					
						
							|  |  |  |   	*init_values = fullinit; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  |   return isam; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2012-03-19 22:32:37 +08:00
										 |  |  | TEST_UNSAFE(ISAM2, AddVariables) { | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create initial state
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values theta; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |   theta.insert((0), Pose2(.1, .2, .3)); | 
					
						
							|  |  |  |   theta.insert(100, Point2(.4, .5)); | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values newTheta; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |   newTheta.insert((1), Pose2(.6, .7, .8)); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   VectorValues deltaUnpermuted; | 
					
						
							| 
									
										
										
										
											2011-10-26 10:04:06 +08:00
										 |  |  |   deltaUnpermuted.insert(0, Vector_(3, .1, .2, .3)); | 
					
						
							|  |  |  |   deltaUnpermuted.insert(1, Vector_(2, .4, .5)); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Permutation permutation(2); | 
					
						
							|  |  |  |   permutation[0] = 1; | 
					
						
							|  |  |  |   permutation[1] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Permuted<VectorValues> delta(permutation, deltaUnpermuted); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-19 22:32:37 +08:00
										 |  |  |   VectorValues deltaNewtonUnpermuted; | 
					
						
							|  |  |  |   deltaNewtonUnpermuted.insert(0, Vector_(3, .1, .2, .3)); | 
					
						
							|  |  |  |   deltaNewtonUnpermuted.insert(1, Vector_(2, .4, .5)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Permutation permutationNewton(2); | 
					
						
							|  |  |  |   permutationNewton[0] = 1; | 
					
						
							|  |  |  |   permutationNewton[1] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Permuted<VectorValues> deltaNewton(permutationNewton, deltaNewtonUnpermuted); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   VectorValues deltaRgUnpermuted; | 
					
						
							|  |  |  |   deltaRgUnpermuted.insert(0, Vector_(3, .1, .2, .3)); | 
					
						
							|  |  |  |   deltaRgUnpermuted.insert(1, Vector_(2, .4, .5)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Permutation permutationRg(2); | 
					
						
							|  |  |  |   permutationRg[0] = 1; | 
					
						
							|  |  |  |   permutationRg[1] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Permuted<VectorValues> deltaRg(permutationRg, deltaRgUnpermuted); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-12 06:10:51 +08:00
										 |  |  |   vector<bool> replacedKeys(2, false); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |   Ordering ordering; ordering += 100, (0); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   ISAM2::Nodes nodes(2); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Verify initial state
 | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |   LONGS_EQUAL(0, ordering[100]); | 
					
						
							|  |  |  |   LONGS_EQUAL(1, ordering[(0)]); | 
					
						
							|  |  |  |   EXPECT(assert_equal(deltaUnpermuted[1], delta[ordering[100]])); | 
					
						
							|  |  |  |   EXPECT(assert_equal(deltaUnpermuted[0], delta[ordering[(0)]])); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create expected state
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values thetaExpected; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |   thetaExpected.insert((0), Pose2(.1, .2, .3)); | 
					
						
							|  |  |  |   thetaExpected.insert(100, Point2(.4, .5)); | 
					
						
							|  |  |  |   thetaExpected.insert((1), Pose2(.6, .7, .8)); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   VectorValues deltaUnpermutedExpected; | 
					
						
							| 
									
										
										
										
											2011-10-26 10:04:06 +08:00
										 |  |  |   deltaUnpermutedExpected.insert(0, Vector_(3, .1, .2, .3)); | 
					
						
							|  |  |  |   deltaUnpermutedExpected.insert(1, Vector_(2, .4, .5)); | 
					
						
							|  |  |  |   deltaUnpermutedExpected.insert(2, Vector_(3, 0.0, 0.0, 0.0)); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Permutation permutationExpected(3); | 
					
						
							|  |  |  |   permutationExpected[0] = 1; | 
					
						
							|  |  |  |   permutationExpected[1] = 0; | 
					
						
							|  |  |  |   permutationExpected[2] = 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Permuted<VectorValues> deltaExpected(permutationExpected, deltaUnpermutedExpected); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-19 22:32:37 +08:00
										 |  |  |   VectorValues deltaNewtonUnpermutedExpected; | 
					
						
							|  |  |  |   deltaNewtonUnpermutedExpected.insert(0, Vector_(3, .1, .2, .3)); | 
					
						
							|  |  |  |   deltaNewtonUnpermutedExpected.insert(1, Vector_(2, .4, .5)); | 
					
						
							|  |  |  |   deltaNewtonUnpermutedExpected.insert(2, Vector_(3, 0.0, 0.0, 0.0)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Permutation permutationNewtonExpected(3); | 
					
						
							|  |  |  |   permutationNewtonExpected[0] = 1; | 
					
						
							|  |  |  |   permutationNewtonExpected[1] = 0; | 
					
						
							|  |  |  |   permutationNewtonExpected[2] = 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Permuted<VectorValues> deltaNewtonExpected(permutationNewtonExpected, deltaNewtonUnpermutedExpected); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   VectorValues deltaRgUnpermutedExpected; | 
					
						
							|  |  |  |   deltaRgUnpermutedExpected.insert(0, Vector_(3, .1, .2, .3)); | 
					
						
							|  |  |  |   deltaRgUnpermutedExpected.insert(1, Vector_(2, .4, .5)); | 
					
						
							|  |  |  |   deltaRgUnpermutedExpected.insert(2, Vector_(3, 0.0, 0.0, 0.0)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Permutation permutationRgExpected(3); | 
					
						
							|  |  |  |   permutationRgExpected[0] = 1; | 
					
						
							|  |  |  |   permutationRgExpected[1] = 0; | 
					
						
							|  |  |  |   permutationRgExpected[2] = 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Permuted<VectorValues> deltaRgExpected(permutationRgExpected, deltaRgUnpermutedExpected); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-12 06:10:51 +08:00
										 |  |  |   vector<bool> replacedKeysExpected(3, false); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |   Ordering orderingExpected; orderingExpected += 100, (0), (1); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   ISAM2::Nodes nodesExpected( | 
					
						
							|  |  |  |           3, ISAM2::sharedClique()); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Expand initial state
 | 
					
						
							| 
									
										
										
										
											2012-03-19 22:32:37 +08:00
										 |  |  |   ISAM2::Impl::AddVariables(newTheta, theta, delta, deltaNewton, deltaRg, replacedKeys, ordering, nodes); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   EXPECT(assert_equal(thetaExpected, theta)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(deltaUnpermutedExpected, deltaUnpermuted)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(deltaExpected.permutation(), delta.permutation())); | 
					
						
							| 
									
										
										
										
											2012-03-19 22:32:37 +08:00
										 |  |  |   EXPECT(assert_equal(deltaNewtonUnpermutedExpected, deltaNewtonUnpermuted)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(deltaNewtonExpected.permutation(), deltaNewton.permutation())); | 
					
						
							|  |  |  |   EXPECT(assert_equal(deltaRgUnpermutedExpected, deltaRgUnpermuted)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(deltaRgExpected.permutation(), deltaRg.permutation())); | 
					
						
							| 
									
										
										
										
											2012-03-12 06:10:51 +08:00
										 |  |  |   EXPECT(assert_container_equality(replacedKeysExpected, replacedKeys)); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  |   EXPECT(assert_equal(orderingExpected, ordering)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-07 23:42:49 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | //TEST(ISAM2, IndicesFromFactors) {
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //  using namespace gtsam::planarSLAM;
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  | //  typedef GaussianISAM2<Values>::Impl Impl;
 | 
					
						
							| 
									
										
										
										
											2011-09-07 23:42:49 +08:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  | //  Ordering ordering; ordering += (0), (0), (1);
 | 
					
						
							| 
									
										
										
										
											2011-09-07 23:42:49 +08:00
										 |  |  | //  planarSLAM::Graph graph;
 | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  | //  graph.addPrior((0), Pose2(), sharedUnit(Pose2::dimension));
 | 
					
						
							|  |  |  | //  graph.addRange((0), (0), 1.0, sharedUnit(1));
 | 
					
						
							| 
									
										
										
										
											2011-09-07 23:42:49 +08:00
										 |  |  | //
 | 
					
						
							|  |  |  | //  FastSet<Index> expected;
 | 
					
						
							|  |  |  | //  expected.insert(0);
 | 
					
						
							|  |  |  | //  expected.insert(1);
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //  FastSet<Index> actual = Impl::IndicesFromFactors(ordering, graph);
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //  EXPECT(assert_equal(expected, actual));
 | 
					
						
							|  |  |  | //}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | //TEST(ISAM2, CheckRelinearization) {
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  | //  typedef GaussianISAM2<Values>::Impl Impl;
 | 
					
						
							| 
									
										
										
										
											2011-09-07 23:42:49 +08:00
										 |  |  | //
 | 
					
						
							|  |  |  | //  // Create values where indices 1 and 3 are above the threshold of 0.1
 | 
					
						
							|  |  |  | //  VectorValues values;
 | 
					
						
							|  |  |  | //  values.reserve(4, 10);
 | 
					
						
							|  |  |  | //  values.push_back_preallocated(Vector_(2, 0.09, 0.09));
 | 
					
						
							|  |  |  | //  values.push_back_preallocated(Vector_(3, 0.11, 0.11, 0.09));
 | 
					
						
							|  |  |  | //  values.push_back_preallocated(Vector_(3, 0.09, 0.09, 0.09));
 | 
					
						
							|  |  |  | //  values.push_back_preallocated(Vector_(2, 0.11, 0.11));
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //  // Create a permutation
 | 
					
						
							|  |  |  | //  Permutation permutation(4);
 | 
					
						
							|  |  |  | //  permutation[0] = 2;
 | 
					
						
							|  |  |  | //  permutation[1] = 0;
 | 
					
						
							|  |  |  | //  permutation[2] = 1;
 | 
					
						
							|  |  |  | //  permutation[3] = 3;
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //  Permuted<VectorValues> permuted(permutation, values);
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //  // After permutation, the indices above the threshold are 2 and 2
 | 
					
						
							|  |  |  | //  FastSet<Index> expected;
 | 
					
						
							|  |  |  | //  expected.insert(2);
 | 
					
						
							|  |  |  | //  expected.insert(3);
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //  // Indices checked by CheckRelinearization
 | 
					
						
							|  |  |  | //  FastSet<Index> actual = Impl::CheckRelinearization(permuted, 0.1);
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //  EXPECT(assert_equal(expected, actual));
 | 
					
						
							|  |  |  | //}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | TEST(ISAM2, optimize2) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Create initialization
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values theta; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |   theta.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create conditional
 | 
					
						
							|  |  |  |   Vector d(3); d << -0.1, -0.1, -0.31831; | 
					
						
							|  |  |  |   Matrix R(3,3); R << | 
					
						
							|  |  |  |       10,          0.0,          0.0, | 
					
						
							|  |  |  |       0.0,           10,          0.0, | 
					
						
							|  |  |  |       0.0,          0.0,   31.8309886; | 
					
						
							|  |  |  |   GaussianConditional::shared_ptr conditional(new GaussianConditional(0, d, R, Vector::Ones(3))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Create ordering
 | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |   Ordering ordering; ordering += (0); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Expected vector
 | 
					
						
							|  |  |  |   VectorValues expected(1, 3); | 
					
						
							|  |  |  |   conditional->solveInPlace(expected); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Clique
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   ISAM2::sharedClique clique( | 
					
						
							|  |  |  |       ISAM2::Clique::Create(make_pair(conditional,GaussianFactor::shared_ptr()))); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  |   VectorValues actual(theta.dims(ordering)); | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   internal::optimizeInPlace<ISAM2::Base>(clique, actual); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | //  expected.print("expected: ");
 | 
					
						
							|  |  |  | //  actual.print("actual: ");
 | 
					
						
							|  |  |  |   EXPECT(assert_equal(expected, actual)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  | bool isam_check(const planarSLAM::Graph& fullgraph, const Values& fullinit, const ISAM2& isam) { | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values actual = isam.calculateEstimate(); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  |   Ordering ordering = isam.getOrdering(); // *fullgraph.orderingCOLAMD(fullinit).first;
 | 
					
						
							|  |  |  |   GaussianFactorGraph linearized = *fullgraph.linearize(fullinit, ordering); | 
					
						
							|  |  |  | //  linearized.print("Expected linearized: ");
 | 
					
						
							|  |  |  |   GaussianBayesNet gbn = *GaussianSequentialSolver(linearized).eliminate(); | 
					
						
							|  |  |  | //  gbn.print("Expected bayesnet: ");
 | 
					
						
							|  |  |  |   VectorValues delta = optimize(gbn); | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values expected = fullinit.retract(delta, ordering); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return assert_equal(expected, actual); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2011-12-15 23:37:52 +08:00
										 |  |  | TEST(ISAM2, slamlike_solution_gaussnewton) | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // These variables will be reused and accumulate factors and values
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   ISAM2 isam(ISAM2Params(ISAM2GaussNewtonParams(0.001), 0.0, 0, false)); | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values fullinit; | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  |   planarSLAM::Graph fullgraph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // i keeps track of the time step
 | 
					
						
							|  |  |  |   size_t i = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add a prior at time 0 and update isam
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addPrior(0, Pose2(0.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-02 05:53:57 +08:00
										 |  |  |     isam.update(newfactors, init); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-15 23:37:52 +08:00
										 |  |  |   CHECK(isam_check(fullgraph, fullinit, isam)); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 0 to time 5
 | 
					
						
							|  |  |  |   for( ; i<5; ++i) { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-02 05:53:57 +08:00
										 |  |  |     isam.update(newfactors, init); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 5 to 6 and landmark measurement at time 5
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     newfactors.addBearingRange(i, 100, Rot2::fromAngle(M_PI/4.0), 5.0, brNoise); | 
					
						
							|  |  |  |     newfactors.addBearingRange(i, 101, Rot2::fromAngle(-M_PI/4.0), 5.0, brNoise); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(1.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     init.insert(100, Point2(5.0/sqrt(2.0), 5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     init.insert(101, Point2(5.0/sqrt(2.0), -5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(1.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert(100, Point2(5.0/sqrt(2.0), 5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     fullinit.insert(101, Point2(5.0/sqrt(2.0), -5.0/sqrt(2.0))); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-02 05:53:57 +08:00
										 |  |  |     isam.update(newfactors, init); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  |     ++ i; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 6 to time 10
 | 
					
						
							|  |  |  |   for( ; i<10; ++i) { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-02 05:53:57 +08:00
										 |  |  |     isam.update(newfactors, init); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 10 to 11 and landmark measurement at time 10
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     newfactors.addBearingRange(i, 100, Rot2::fromAngle(M_PI/4.0 + M_PI/16.0), 4.5, brNoise); | 
					
						
							|  |  |  |     newfactors.addBearingRange(i, 101, Rot2::fromAngle(-M_PI/4.0 + M_PI/16.0), 4.5, brNoise); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(6.9, 0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(6.9, 0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-02 05:53:57 +08:00
										 |  |  |     isam.update(newfactors, init); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  |     ++ i; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Compare solutions
 | 
					
						
							| 
									
										
										
										
											2011-12-15 23:37:52 +08:00
										 |  |  |   CHECK(isam_check(fullgraph, fullinit, isam)); | 
					
						
							| 
									
										
										
										
											2011-12-14 06:54:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-15 08:08:57 +08:00
										 |  |  |   // Check gradient at each node
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   typedef ISAM2::sharedClique sharedClique; | 
					
						
							| 
									
										
										
										
											2011-12-15 08:08:57 +08:00
										 |  |  |   BOOST_FOREACH(const sharedClique& clique, isam.nodes()) { | 
					
						
							|  |  |  |     // Compute expected gradient
 | 
					
						
							|  |  |  |     FactorGraph<JacobianFactor> jfg; | 
					
						
							|  |  |  |     jfg.push_back(JacobianFactor::shared_ptr(new JacobianFactor(*clique->conditional()))); | 
					
						
							|  |  |  |     VectorValues expectedGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |     gradientAtZero(jfg, expectedGradient); | 
					
						
							|  |  |  |     // Compare with actual gradients
 | 
					
						
							|  |  |  |     int variablePosition = 0; | 
					
						
							|  |  |  |     for(GaussianConditional::const_iterator jit = clique->conditional()->begin(); jit != clique->conditional()->end(); ++jit) { | 
					
						
							|  |  |  |       const int dim = clique->conditional()->dim(jit); | 
					
						
							|  |  |  |       Vector actual = clique->gradientContribution().segment(variablePosition, dim); | 
					
						
							|  |  |  |       EXPECT(assert_equal(expectedGradient[*jit], actual)); | 
					
						
							|  |  |  |       variablePosition += dim; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     LONGS_EQUAL(clique->gradientContribution().rows(), variablePosition); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 06:54:11 +08:00
										 |  |  |   // Check gradient
 | 
					
						
							|  |  |  |   VectorValues expectedGradient(*allocateVectorValues(isam)); | 
					
						
							| 
									
										
										
										
											2011-12-15 08:08:57 +08:00
										 |  |  |   gradientAtZero(FactorGraph<JacobianFactor>(isam), expectedGradient); | 
					
						
							|  |  |  |   VectorValues expectedGradient2(gradient(FactorGraph<JacobianFactor>(isam), VectorValues::Zero(expectedGradient))); | 
					
						
							|  |  |  |   VectorValues actualGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |   gradientAtZero(isam, actualGradient); | 
					
						
							|  |  |  |   EXPECT(assert_equal(expectedGradient2, expectedGradient)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(expectedGradient, actualGradient)); | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-13 00:03:52 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2011-12-15 23:37:52 +08:00
										 |  |  | TEST(ISAM2, slamlike_solution_dogleg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // These variables will be reused and accumulate factors and values
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   ISAM2 isam(ISAM2Params(ISAM2DoglegParams(1.0), 0.0, 0, false)); | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values fullinit; | 
					
						
							| 
									
										
										
										
											2011-12-15 23:37:52 +08:00
										 |  |  |   planarSLAM::Graph fullgraph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // i keeps track of the time step
 | 
					
						
							|  |  |  |   size_t i = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add a prior at time 0 and update isam
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addPrior(0, Pose2(0.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							| 
									
										
										
										
											2011-12-15 23:37:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   CHECK(isam_check(fullgraph, fullinit, isam)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 0 to time 5
 | 
					
						
							|  |  |  |   for( ; i<5; ++i) { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2011-12-15 23:37:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 5 to 6 and landmark measurement at time 5
 | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     newfactors.addBearingRange(i, 100, Rot2::fromAngle(M_PI/4.0), 5.0, brNoise); | 
					
						
							|  |  |  |     newfactors.addBearingRange(i, 101, Rot2::fromAngle(-M_PI/4.0), 5.0, brNoise); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(1.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     init.insert(100, Point2(5.0/sqrt(2.0), 5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     init.insert(101, Point2(5.0/sqrt(2.0), -5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(1.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert(100, Point2(5.0/sqrt(2.0), 5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     fullinit.insert(101, Point2(5.0/sqrt(2.0), -5.0/sqrt(2.0))); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |     ++ i; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 6 to time 10
 | 
					
						
							|  |  |  |   for( ; i<10; ++i) { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 10 to 11 and landmark measurement at time 10
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     newfactors.addBearingRange(i, 100, Rot2::fromAngle(M_PI/4.0 + M_PI/16.0), 4.5, brNoise); | 
					
						
							|  |  |  |     newfactors.addBearingRange(i, 101, Rot2::fromAngle(-M_PI/4.0 + M_PI/16.0), 4.5, brNoise); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(6.9, 0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(6.9, 0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |     ++ i; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Compare solutions
 | 
					
						
							|  |  |  |   CHECK(isam_check(fullgraph, fullinit, isam)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Check gradient at each node
 | 
					
						
							|  |  |  |   typedef ISAM2::sharedClique sharedClique; | 
					
						
							|  |  |  |   BOOST_FOREACH(const sharedClique& clique, isam.nodes()) { | 
					
						
							|  |  |  |     // Compute expected gradient
 | 
					
						
							|  |  |  |     FactorGraph<JacobianFactor> jfg; | 
					
						
							|  |  |  |     jfg.push_back(JacobianFactor::shared_ptr(new JacobianFactor(*clique->conditional()))); | 
					
						
							|  |  |  |     VectorValues expectedGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |     gradientAtZero(jfg, expectedGradient); | 
					
						
							|  |  |  |     // Compare with actual gradients
 | 
					
						
							|  |  |  |     int variablePosition = 0; | 
					
						
							|  |  |  |     for(GaussianConditional::const_iterator jit = clique->conditional()->begin(); jit != clique->conditional()->end(); ++jit) { | 
					
						
							|  |  |  |       const int dim = clique->conditional()->dim(jit); | 
					
						
							|  |  |  |       Vector actual = clique->gradientContribution().segment(variablePosition, dim); | 
					
						
							|  |  |  |       EXPECT(assert_equal(expectedGradient[*jit], actual)); | 
					
						
							|  |  |  |       variablePosition += dim; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     LONGS_EQUAL(clique->gradientContribution().rows(), variablePosition); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Check gradient
 | 
					
						
							|  |  |  |   VectorValues expectedGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |   gradientAtZero(FactorGraph<JacobianFactor>(isam), expectedGradient); | 
					
						
							|  |  |  |   VectorValues expectedGradient2(gradient(FactorGraph<JacobianFactor>(isam), VectorValues::Zero(expectedGradient))); | 
					
						
							|  |  |  |   VectorValues actualGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |   gradientAtZero(isam, actualGradient); | 
					
						
							|  |  |  |   EXPECT(assert_equal(expectedGradient2, expectedGradient)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(expectedGradient, actualGradient)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | TEST(ISAM2, slamlike_solution_gaussnewton_qr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // These variables will be reused and accumulate factors and values
 | 
					
						
							|  |  |  |   ISAM2 isam(ISAM2Params(ISAM2GaussNewtonParams(0.001), 0.0, 0, false, false, ISAM2Params::QR)); | 
					
						
							|  |  |  |   Values fullinit; | 
					
						
							|  |  |  |   planarSLAM::Graph fullgraph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // i keeps track of the time step
 | 
					
						
							|  |  |  |   size_t i = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add a prior at time 0 and update isam
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addPrior(0, Pose2(0.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   CHECK(isam_check(fullgraph, fullinit, isam)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 0 to time 5
 | 
					
						
							|  |  |  |   for( ; i<5; ++i) { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 5 to 6 and landmark measurement at time 5
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     newfactors.addBearingRange(i, 100, Rot2::fromAngle(M_PI/4.0), 5.0, brNoise); | 
					
						
							|  |  |  |     newfactors.addBearingRange(i, 101, Rot2::fromAngle(-M_PI/4.0), 5.0, brNoise); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(1.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     init.insert(100, Point2(5.0/sqrt(2.0), 5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     init.insert(101, Point2(5.0/sqrt(2.0), -5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(1.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert(100, Point2(5.0/sqrt(2.0), 5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     fullinit.insert(101, Point2(5.0/sqrt(2.0), -5.0/sqrt(2.0))); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |     ++ i; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 6 to time 10
 | 
					
						
							|  |  |  |   for( ; i<10; ++i) { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 10 to 11 and landmark measurement at time 10
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     newfactors.addBearingRange(i, 100, Rot2::fromAngle(M_PI/4.0 + M_PI/16.0), 4.5, brNoise); | 
					
						
							|  |  |  |     newfactors.addBearingRange(i, 101, Rot2::fromAngle(-M_PI/4.0 + M_PI/16.0), 4.5, brNoise); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(6.9, 0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(6.9, 0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |     ++ i; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Compare solutions
 | 
					
						
							|  |  |  |   CHECK(isam_check(fullgraph, fullinit, isam)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Check gradient at each node
 | 
					
						
							|  |  |  |   typedef ISAM2::sharedClique sharedClique; | 
					
						
							|  |  |  |   BOOST_FOREACH(const sharedClique& clique, isam.nodes()) { | 
					
						
							|  |  |  |     // Compute expected gradient
 | 
					
						
							|  |  |  |     FactorGraph<JacobianFactor> jfg; | 
					
						
							|  |  |  |     jfg.push_back(JacobianFactor::shared_ptr(new JacobianFactor(*clique->conditional()))); | 
					
						
							|  |  |  |     VectorValues expectedGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |     gradientAtZero(jfg, expectedGradient); | 
					
						
							|  |  |  |     // Compare with actual gradients
 | 
					
						
							|  |  |  |     int variablePosition = 0; | 
					
						
							|  |  |  |     for(GaussianConditional::const_iterator jit = clique->conditional()->begin(); jit != clique->conditional()->end(); ++jit) { | 
					
						
							|  |  |  |       const int dim = clique->conditional()->dim(jit); | 
					
						
							|  |  |  |       Vector actual = clique->gradientContribution().segment(variablePosition, dim); | 
					
						
							|  |  |  |       EXPECT(assert_equal(expectedGradient[*jit], actual)); | 
					
						
							|  |  |  |       variablePosition += dim; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     LONGS_EQUAL(clique->gradientContribution().rows(), variablePosition); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Check gradient
 | 
					
						
							|  |  |  |   VectorValues expectedGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |   gradientAtZero(FactorGraph<JacobianFactor>(isam), expectedGradient); | 
					
						
							|  |  |  |   VectorValues expectedGradient2(gradient(FactorGraph<JacobianFactor>(isam), VectorValues::Zero(expectedGradient))); | 
					
						
							|  |  |  |   VectorValues actualGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |   gradientAtZero(isam, actualGradient); | 
					
						
							|  |  |  |   EXPECT(assert_equal(expectedGradient2, expectedGradient)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(expectedGradient, actualGradient)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | TEST(ISAM2, slamlike_solution_dogleg_qr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // These variables will be reused and accumulate factors and values
 | 
					
						
							|  |  |  |   ISAM2 isam(ISAM2Params(ISAM2DoglegParams(1.0), 0.0, 0, false, false, ISAM2Params::QR)); | 
					
						
							|  |  |  |   Values fullinit; | 
					
						
							|  |  |  |   planarSLAM::Graph fullgraph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // i keeps track of the time step
 | 
					
						
							|  |  |  |   size_t i = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add a prior at time 0 and update isam
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addPrior(0, Pose2(0.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   CHECK(isam_check(fullgraph, fullinit, isam)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 0 to time 5
 | 
					
						
							|  |  |  |   for( ; i<5; ++i) { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:30:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 5 to 6 and landmark measurement at time 5
 | 
					
						
							| 
									
										
										
										
											2011-12-15 23:37:52 +08:00
										 |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     newfactors.addBearingRange(i, 100, Rot2::fromAngle(M_PI/4.0), 5.0, brNoise); | 
					
						
							|  |  |  |     newfactors.addBearingRange(i, 101, Rot2::fromAngle(-M_PI/4.0), 5.0, brNoise); | 
					
						
							| 
									
										
										
										
											2011-12-15 23:37:52 +08:00
										 |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(1.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     init.insert(100, Point2(5.0/sqrt(2.0), 5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     init.insert(101, Point2(5.0/sqrt(2.0), -5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(1.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert(100, Point2(5.0/sqrt(2.0), 5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     fullinit.insert(101, Point2(5.0/sqrt(2.0), -5.0/sqrt(2.0))); | 
					
						
							| 
									
										
										
										
											2011-12-15 23:37:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |     ++ i; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 6 to time 10
 | 
					
						
							|  |  |  |   for( ; i<10; ++i) { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2011-12-15 23:37:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 10 to 11 and landmark measurement at time 10
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     newfactors.addBearingRange(i, 100, Rot2::fromAngle(M_PI/4.0 + M_PI/16.0), 4.5, brNoise); | 
					
						
							|  |  |  |     newfactors.addBearingRange(i, 101, Rot2::fromAngle(-M_PI/4.0 + M_PI/16.0), 4.5, brNoise); | 
					
						
							| 
									
										
										
										
											2011-12-15 23:37:52 +08:00
										 |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(6.9, 0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(6.9, 0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2011-12-15 23:37:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |     ++ i; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Compare solutions
 | 
					
						
							|  |  |  |   CHECK(isam_check(fullgraph, fullinit, isam)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Check gradient at each node
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   typedef ISAM2::sharedClique sharedClique; | 
					
						
							| 
									
										
										
										
											2011-12-15 23:37:52 +08:00
										 |  |  |   BOOST_FOREACH(const sharedClique& clique, isam.nodes()) { | 
					
						
							|  |  |  |     // Compute expected gradient
 | 
					
						
							|  |  |  |     FactorGraph<JacobianFactor> jfg; | 
					
						
							|  |  |  |     jfg.push_back(JacobianFactor::shared_ptr(new JacobianFactor(*clique->conditional()))); | 
					
						
							|  |  |  |     VectorValues expectedGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |     gradientAtZero(jfg, expectedGradient); | 
					
						
							|  |  |  |     // Compare with actual gradients
 | 
					
						
							|  |  |  |     int variablePosition = 0; | 
					
						
							|  |  |  |     for(GaussianConditional::const_iterator jit = clique->conditional()->begin(); jit != clique->conditional()->end(); ++jit) { | 
					
						
							|  |  |  |       const int dim = clique->conditional()->dim(jit); | 
					
						
							|  |  |  |       Vector actual = clique->gradientContribution().segment(variablePosition, dim); | 
					
						
							|  |  |  |       EXPECT(assert_equal(expectedGradient[*jit], actual)); | 
					
						
							|  |  |  |       variablePosition += dim; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     LONGS_EQUAL(clique->gradientContribution().rows(), variablePosition); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Check gradient
 | 
					
						
							|  |  |  |   VectorValues expectedGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |   gradientAtZero(FactorGraph<JacobianFactor>(isam), expectedGradient); | 
					
						
							|  |  |  |   VectorValues expectedGradient2(gradient(FactorGraph<JacobianFactor>(isam), VectorValues::Zero(expectedGradient))); | 
					
						
							|  |  |  |   VectorValues actualGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |   gradientAtZero(isam, actualGradient); | 
					
						
							|  |  |  |   EXPECT(assert_equal(expectedGradient2, expectedGradient)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(expectedGradient, actualGradient)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | TEST(ISAM2, clone) { | 
					
						
							| 
									
										
										
										
											2011-12-13 00:03:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  |   ISAM2 clone1; | 
					
						
							| 
									
										
										
										
											2011-12-13 00:03:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  |     ISAM2 isam = createSlamlikeISAM2(); | 
					
						
							|  |  |  |     clone1 = isam; | 
					
						
							| 
									
										
										
										
											2011-12-13 00:03:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  |     ISAM2 clone2(isam); | 
					
						
							| 
									
										
										
										
											2011-12-13 00:03:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  |     // Modify original isam
 | 
					
						
							|  |  |  |     NonlinearFactorGraph factors; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     factors.add(BetweenFactor<Pose2>(0, 10, | 
					
						
							|  |  |  |         isam.calculateEstimate<Pose2>(0).between(isam.calculateEstimate<Pose2>(10)), sharedUnit(3))); | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  |     isam.update(factors); | 
					
						
							| 
									
										
										
										
											2011-12-13 00:03:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  |     CHECK(assert_equal(createSlamlikeISAM2(), clone2)); | 
					
						
							| 
									
										
										
										
											2011-12-13 00:03:52 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  |   // This is to (perhaps unsuccessfully) try to currupt unallocated memory referenced
 | 
					
						
							|  |  |  |   // if the references in the iSAM2 copy point to the old instance which deleted at
 | 
					
						
							|  |  |  |   // the end of the {...} section above.
 | 
					
						
							|  |  |  |   ISAM2 temp = createSlamlikeISAM2(); | 
					
						
							| 
									
										
										
										
											2011-12-13 00:03:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-07 02:56:07 +08:00
										 |  |  |   CHECK(assert_equal(createSlamlikeISAM2(), clone1)); | 
					
						
							|  |  |  |   CHECK(assert_equal(clone1, temp)); | 
					
						
							| 
									
										
										
										
											2012-04-09 11:02:11 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Check clone empty
 | 
					
						
							|  |  |  |   ISAM2 isam; | 
					
						
							|  |  |  |   clone1 = isam; | 
					
						
							|  |  |  |   CHECK(assert_equal(ISAM2(), clone1)); | 
					
						
							| 
									
										
										
										
											2011-12-13 00:03:52 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 02:46:31 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | TEST(ISAM2, permute_cached) { | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   typedef boost::shared_ptr<ISAM2Clique> sharedISAM2Clique; | 
					
						
							| 
									
										
										
										
											2011-12-14 02:46:31 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Construct expected permuted BayesTree (variable 2 has been changed to 1)
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   BayesTree<GaussianConditional, ISAM2Clique> expected; | 
					
						
							|  |  |  |   expected.insert(sharedISAM2Clique(new ISAM2Clique(make_pair( | 
					
						
							| 
									
										
										
										
											2011-12-14 02:46:31 +08:00
										 |  |  |       boost::make_shared<GaussianConditional>(pair_list_of | 
					
						
							|  |  |  |           (3, Matrix_(1,1,1.0)) | 
					
						
							|  |  |  |           (4, Matrix_(1,1,2.0)), | 
					
						
							|  |  |  |           2, Vector_(1,1.0), Vector_(1,1.0)),   // p(3,4)
 | 
					
						
							|  |  |  |       HessianFactor::shared_ptr()))));          // Cached: empty
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   expected.insert(sharedISAM2Clique(new ISAM2Clique(make_pair( | 
					
						
							| 
									
										
										
										
											2011-12-14 02:46:31 +08:00
										 |  |  |       boost::make_shared<GaussianConditional>(pair_list_of | 
					
						
							|  |  |  |           (2, Matrix_(1,1,1.0)) | 
					
						
							|  |  |  |           (3, Matrix_(1,1,2.0)), | 
					
						
							|  |  |  |           1, Vector_(1,1.0), Vector_(1,1.0)),     // p(2|3)
 | 
					
						
							|  |  |  |       boost::make_shared<HessianFactor>(3, Matrix_(1,1,1.0), Vector_(1,1.0), 0.0))))); // Cached: p(3)
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   expected.insert(sharedISAM2Clique(new ISAM2Clique(make_pair( | 
					
						
							| 
									
										
										
										
											2011-12-14 02:46:31 +08:00
										 |  |  |       boost::make_shared<GaussianConditional>(pair_list_of | 
					
						
							|  |  |  |           (0, Matrix_(1,1,1.0)) | 
					
						
							|  |  |  |           (2, Matrix_(1,1,2.0)), | 
					
						
							|  |  |  |           1, Vector_(1,1.0), Vector_(1,1.0)),     // p(0|2)
 | 
					
						
							|  |  |  |       boost::make_shared<HessianFactor>(1, Matrix_(1,1,1.0), Vector_(1,1.0), 0.0))))); // Cached: p(1)
 | 
					
						
							|  |  |  |   // Change variable 2 to 1
 | 
					
						
							|  |  |  |   expected.root()->children().front()->conditional()->keys()[0] = 1; | 
					
						
							|  |  |  |   expected.root()->children().front()->children().front()->conditional()->keys()[1] = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Construct unpermuted BayesTree
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   BayesTree<GaussianConditional, ISAM2Clique> actual; | 
					
						
							|  |  |  |   actual.insert(sharedISAM2Clique(new ISAM2Clique(make_pair( | 
					
						
							| 
									
										
										
										
											2011-12-14 02:46:31 +08:00
										 |  |  |       boost::make_shared<GaussianConditional>(pair_list_of | 
					
						
							|  |  |  |           (3, Matrix_(1,1,1.0)) | 
					
						
							|  |  |  |           (4, Matrix_(1,1,2.0)), | 
					
						
							|  |  |  |           2, Vector_(1,1.0), Vector_(1,1.0)),   // p(3,4)
 | 
					
						
							|  |  |  |       HessianFactor::shared_ptr()))));          // Cached: empty
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   actual.insert(sharedISAM2Clique(new ISAM2Clique(make_pair( | 
					
						
							| 
									
										
										
										
											2011-12-14 02:46:31 +08:00
										 |  |  |       boost::make_shared<GaussianConditional>(pair_list_of | 
					
						
							|  |  |  |           (2, Matrix_(1,1,1.0)) | 
					
						
							|  |  |  |           (3, Matrix_(1,1,2.0)), | 
					
						
							|  |  |  |           1, Vector_(1,1.0), Vector_(1,1.0)),     // p(2|3)
 | 
					
						
							|  |  |  |       boost::make_shared<HessianFactor>(3, Matrix_(1,1,1.0), Vector_(1,1.0), 0.0))))); // Cached: p(3)
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   actual.insert(sharedISAM2Clique(new ISAM2Clique(make_pair( | 
					
						
							| 
									
										
										
										
											2011-12-14 02:46:31 +08:00
										 |  |  |       boost::make_shared<GaussianConditional>(pair_list_of | 
					
						
							|  |  |  |           (0, Matrix_(1,1,1.0)) | 
					
						
							|  |  |  |           (2, Matrix_(1,1,2.0)), | 
					
						
							|  |  |  |           1, Vector_(1,1.0), Vector_(1,1.0)),     // p(0|2)
 | 
					
						
							|  |  |  |       boost::make_shared<HessianFactor>(2, Matrix_(1,1,1.0), Vector_(1,1.0), 0.0))))); // Cached: p(2)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Create permutation that changes variable 2 -> 0
 | 
					
						
							|  |  |  |   Permutation permutation = Permutation::Identity(5); | 
					
						
							|  |  |  |   permutation[2] = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Permute BayesTree
 | 
					
						
							|  |  |  |   actual.root()->permuteWithInverse(permutation); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Check
 | 
					
						
							|  |  |  |   EXPECT(assert_equal(expected, actual)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-04 01:50:48 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | TEST(ISAM2, removeFactors) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // This test builds a graph in the same way as the "slamlike" test above, but
 | 
					
						
							|  |  |  |   // then removes the 2nd-to-last landmark measurement
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // These variables will be reused and accumulate factors and values
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   ISAM2 isam(ISAM2Params(ISAM2GaussNewtonParams(0.001), 0.0, 0, false)); | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values fullinit; | 
					
						
							| 
									
										
										
										
											2012-01-04 01:50:48 +08:00
										 |  |  |   planarSLAM::Graph fullgraph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // i keeps track of the time step
 | 
					
						
							|  |  |  |   size_t i = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add a prior at time 0 and update isam
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addPrior(0, Pose2(0.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-01-04 01:50:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   CHECK(isam_check(fullgraph, fullinit, isam)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 0 to time 5
 | 
					
						
							|  |  |  |   for( ; i<5; ++i) { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-01-04 01:50:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 5 to 6 and landmark measurement at time 5
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     newfactors.addBearingRange(i, 100, Rot2::fromAngle(M_PI/4.0), 5.0, brNoise); | 
					
						
							|  |  |  |     newfactors.addBearingRange(i, 101, Rot2::fromAngle(-M_PI/4.0), 5.0, brNoise); | 
					
						
							| 
									
										
										
										
											2012-01-04 01:50:48 +08:00
										 |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(1.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     init.insert(100, Point2(5.0/sqrt(2.0), 5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     init.insert(101, Point2(5.0/sqrt(2.0), -5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(1.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert(100, Point2(5.0/sqrt(2.0), 5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     fullinit.insert(101, Point2(5.0/sqrt(2.0), -5.0/sqrt(2.0))); | 
					
						
							| 
									
										
										
										
											2012-01-04 01:50:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |     ++ i; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 6 to time 10
 | 
					
						
							|  |  |  |   for( ; i<10; ++i) { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-01-04 01:50:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 10 to 11 and landmark measurement at time 10
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     newfactors.addBearingRange(i, 100, Rot2::fromAngle(M_PI/4.0 + M_PI/16.0), 4.5, brNoise); | 
					
						
							|  |  |  |     newfactors.addBearingRange(i, 101, Rot2::fromAngle(-M_PI/4.0 + M_PI/16.0), 4.5, brNoise); | 
					
						
							| 
									
										
										
										
											2012-01-04 01:50:48 +08:00
										 |  |  |     fullgraph.push_back(newfactors[0]); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors[2]); // Don't add measurement on landmark 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(6.9, 0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(6.9, 0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-01-04 01:50:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ISAM2Result result = isam.update(newfactors, init); | 
					
						
							|  |  |  |     ++ i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Remove the measurement on landmark 0
 | 
					
						
							|  |  |  |     FastVector<size_t> toRemove; | 
					
						
							| 
									
										
										
										
											2012-05-02 02:54:44 +08:00
										 |  |  |     EXPECT_LONGS_EQUAL(isam.getFactorsUnsafe().size()-2, result.newFactorsIndices[1]); | 
					
						
							| 
									
										
										
										
											2012-01-04 01:50:48 +08:00
										 |  |  |     toRemove.push_back(result.newFactorsIndices[1]); | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     isam.update(planarSLAM::Graph(), Values(), toRemove); | 
					
						
							| 
									
										
										
										
											2012-01-04 01:50:48 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Compare solutions
 | 
					
						
							|  |  |  |   CHECK(isam_check(fullgraph, fullinit, isam)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-04 03:14:00 +08:00
										 |  |  |   // Check gradient at each node
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   typedef ISAM2::sharedClique sharedClique; | 
					
						
							| 
									
										
										
										
											2012-01-04 03:14:00 +08:00
										 |  |  |   BOOST_FOREACH(const sharedClique& clique, isam.nodes()) { | 
					
						
							|  |  |  |     // Compute expected gradient
 | 
					
						
							|  |  |  |     FactorGraph<JacobianFactor> jfg; | 
					
						
							|  |  |  |     jfg.push_back(JacobianFactor::shared_ptr(new JacobianFactor(*clique->conditional()))); | 
					
						
							|  |  |  |     VectorValues expectedGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |     gradientAtZero(jfg, expectedGradient); | 
					
						
							|  |  |  |     // Compare with actual gradients
 | 
					
						
							|  |  |  |     int variablePosition = 0; | 
					
						
							|  |  |  |     for(GaussianConditional::const_iterator jit = clique->conditional()->begin(); jit != clique->conditional()->end(); ++jit) { | 
					
						
							|  |  |  |       const int dim = clique->conditional()->dim(jit); | 
					
						
							|  |  |  |       Vector actual = clique->gradientContribution().segment(variablePosition, dim); | 
					
						
							|  |  |  |       EXPECT(assert_equal(expectedGradient[*jit], actual)); | 
					
						
							|  |  |  |       variablePosition += dim; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     LONGS_EQUAL(clique->gradientContribution().rows(), variablePosition); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Check gradient
 | 
					
						
							|  |  |  |   VectorValues expectedGradient(*allocateVectorValues(isam)); | 
					
						
							| 
									
										
										
										
											2012-05-02 02:54:44 +08:00
										 |  |  |   gradientAtZero(FactorGraph<JacobianFactor>(isam), expectedGradient); | 
					
						
							|  |  |  |   VectorValues expectedGradient2(gradient(FactorGraph<JacobianFactor>(isam), VectorValues::Zero(expectedGradient))); | 
					
						
							|  |  |  |   VectorValues actualGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |   gradientAtZero(isam, actualGradient); | 
					
						
							|  |  |  |   EXPECT(assert_equal(expectedGradient2, expectedGradient)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(expectedGradient, actualGradient)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  | TEST_UNSAFE(ISAM2, swapFactors) | 
					
						
							| 
									
										
										
										
											2012-05-02 02:54:44 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   // This test builds a graph in the same way as the "slamlike" test above, but
 | 
					
						
							|  |  |  |   // then swaps the 2nd-to-last landmark measurement with a different one
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Values fullinit; | 
					
						
							|  |  |  |   planarSLAM::Graph fullgraph; | 
					
						
							|  |  |  |   ISAM2 isam = createSlamlikeISAM2(fullinit, fullgraph); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Remove the measurement on landmark 0 and replace with a different one
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   	size_t swap_idx = isam.getFactorsUnsafe().size()-2; | 
					
						
							|  |  |  |   	FastVector<size_t> toRemove; | 
					
						
							|  |  |  |   	toRemove.push_back(swap_idx); | 
					
						
							|  |  |  |   	fullgraph.remove(swap_idx); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   	planarSLAM::Graph swapfactors; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  | //  	swapfactors.addBearingRange(10, 100, Rot2::fromAngle(M_PI/4.0 + M_PI/16.0), 4.5, brNoise); // original factor
 | 
					
						
							|  |  |  |   	swapfactors.addBearingRange(10, 100, Rot2::fromAngle(M_PI/4.0 + M_PI/16.0), 5.0, brNoise); | 
					
						
							| 
									
										
										
										
											2012-05-02 02:54:44 +08:00
										 |  |  |   	fullgraph.push_back(swapfactors); | 
					
						
							|  |  |  |   	isam.update(swapfactors, Values(), toRemove); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Compare solutions
 | 
					
						
							|  |  |  |   EXPECT(assert_equal(fullgraph, planarSLAM::Graph(isam.getFactorsUnsafe()))); | 
					
						
							|  |  |  |   EXPECT(isam_check(fullgraph, fullinit, isam)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Check gradient at each node
 | 
					
						
							|  |  |  |   typedef ISAM2::sharedClique sharedClique; | 
					
						
							|  |  |  |   BOOST_FOREACH(const sharedClique& clique, isam.nodes()) { | 
					
						
							|  |  |  |     // Compute expected gradient
 | 
					
						
							|  |  |  |     FactorGraph<JacobianFactor> jfg; | 
					
						
							|  |  |  |     jfg.push_back(JacobianFactor::shared_ptr(new JacobianFactor(*clique->conditional()))); | 
					
						
							|  |  |  |     VectorValues expectedGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |     gradientAtZero(jfg, expectedGradient); | 
					
						
							|  |  |  |     // Compare with actual gradients
 | 
					
						
							|  |  |  |     int variablePosition = 0; | 
					
						
							|  |  |  |     for(GaussianConditional::const_iterator jit = clique->conditional()->begin(); jit != clique->conditional()->end(); ++jit) { | 
					
						
							|  |  |  |       const int dim = clique->conditional()->dim(jit); | 
					
						
							|  |  |  |       Vector actual = clique->gradientContribution().segment(variablePosition, dim); | 
					
						
							|  |  |  |       EXPECT(assert_equal(expectedGradient[*jit], actual)); | 
					
						
							|  |  |  |       variablePosition += dim; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     EXPECT_LONGS_EQUAL(clique->gradientContribution().rows(), variablePosition); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Check gradient
 | 
					
						
							|  |  |  |   VectorValues expectedGradient(*allocateVectorValues(isam)); | 
					
						
							| 
									
										
										
										
											2012-01-04 03:14:00 +08:00
										 |  |  |   gradientAtZero(FactorGraph<JacobianFactor>(isam), expectedGradient); | 
					
						
							|  |  |  |   VectorValues expectedGradient2(gradient(FactorGraph<JacobianFactor>(isam), VectorValues::Zero(expectedGradient))); | 
					
						
							|  |  |  |   VectorValues actualGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |   gradientAtZero(isam, actualGradient); | 
					
						
							|  |  |  |   EXPECT(assert_equal(expectedGradient2, expectedGradient)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(expectedGradient, actualGradient)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | TEST(ISAM2, constrained_ordering) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // These variables will be reused and accumulate factors and values
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   ISAM2 isam(ISAM2Params(ISAM2GaussNewtonParams(0.001), 0.0, 0, false)); | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values fullinit; | 
					
						
							| 
									
										
										
										
											2012-01-04 03:14:00 +08:00
										 |  |  |   planarSLAM::Graph fullgraph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // We will constrain x3 and x4 to the end
 | 
					
						
							| 
									
										
										
										
											2012-03-25 00:52:55 +08:00
										 |  |  |   FastMap<Key, int> constrained; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |   constrained.insert(make_pair((3), 1)); | 
					
						
							|  |  |  |   constrained.insert(make_pair((4), 2)); | 
					
						
							| 
									
										
										
										
											2012-01-04 03:14:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // i keeps track of the time step
 | 
					
						
							|  |  |  |   size_t i = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add a prior at time 0 and update isam
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addPrior(0, Pose2(0.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((0), Pose2(0.01, 0.01, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-01-04 03:14:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   CHECK(isam_check(fullgraph, fullinit, isam)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 0 to time 5
 | 
					
						
							|  |  |  |   for( ; i<5; ++i) { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-01-04 03:14:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if(i >= 3) | 
					
						
							|  |  |  |       isam.update(newfactors, init, FastVector<size_t>(), constrained); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       isam.update(newfactors, init); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 5 to 6 and landmark measurement at time 5
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     newfactors.addBearingRange(i, 100, Rot2::fromAngle(M_PI/4.0), 5.0, brNoise); | 
					
						
							|  |  |  |     newfactors.addBearingRange(i, 101, Rot2::fromAngle(-M_PI/4.0), 5.0, brNoise); | 
					
						
							| 
									
										
										
										
											2012-01-04 03:14:00 +08:00
										 |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(1.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     init.insert(100, Point2(5.0/sqrt(2.0), 5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     init.insert(101, Point2(5.0/sqrt(2.0), -5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(1.01, 0.01, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert(100, Point2(5.0/sqrt(2.0), 5.0/sqrt(2.0))); | 
					
						
							|  |  |  |     fullinit.insert(101, Point2(5.0/sqrt(2.0), -5.0/sqrt(2.0))); | 
					
						
							| 
									
										
										
										
											2012-01-04 03:14:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init, FastVector<size_t>(), constrained); | 
					
						
							|  |  |  |     ++ i; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 6 to time 10
 | 
					
						
							|  |  |  |   for( ; i<10; ++i) { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							|  |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(double(i+1)+0.1, -0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-01-04 03:14:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init, FastVector<size_t>(), constrained); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add odometry from time 10 to 11 and landmark measurement at time 10
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     planarSLAM::Graph newfactors; | 
					
						
							|  |  |  |     newfactors.addOdometry(i, i+1, Pose2(1.0, 0.0, 0.0), odoNoise); | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     newfactors.addBearingRange(i, 100, Rot2::fromAngle(M_PI/4.0 + M_PI/16.0), 4.5, brNoise); | 
					
						
							|  |  |  |     newfactors.addBearingRange(i, 101, Rot2::fromAngle(-M_PI/4.0 + M_PI/16.0), 4.5, brNoise); | 
					
						
							| 
									
										
										
										
											2012-01-04 03:14:00 +08:00
										 |  |  |     fullgraph.push_back(newfactors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |     Values init; | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |     init.insert((i+1), Pose2(6.9, 0.1, 0.01)); | 
					
						
							|  |  |  |     fullinit.insert((i+1), Pose2(6.9, 0.1, 0.01)); | 
					
						
							| 
									
										
										
										
											2012-01-04 03:14:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(newfactors, init, FastVector<size_t>(), constrained); | 
					
						
							|  |  |  |     ++ i; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Compare solutions
 | 
					
						
							|  |  |  |   EXPECT(isam_check(fullgraph, fullinit, isam)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Check that x3 and x4 are last, but either can come before the other
 | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  |   EXPECT(isam.getOrdering()[(3)] == 12 && isam.getOrdering()[(4)] == 13); | 
					
						
							| 
									
										
										
										
											2012-01-04 03:14:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-04 01:50:48 +08:00
										 |  |  |   // Check gradient at each node
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:57:42 +08:00
										 |  |  |   typedef ISAM2::sharedClique sharedClique; | 
					
						
							| 
									
										
										
										
											2012-01-04 01:50:48 +08:00
										 |  |  |   BOOST_FOREACH(const sharedClique& clique, isam.nodes()) { | 
					
						
							|  |  |  |     // Compute expected gradient
 | 
					
						
							|  |  |  |     FactorGraph<JacobianFactor> jfg; | 
					
						
							|  |  |  |     jfg.push_back(JacobianFactor::shared_ptr(new JacobianFactor(*clique->conditional()))); | 
					
						
							|  |  |  |     VectorValues expectedGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |     gradientAtZero(jfg, expectedGradient); | 
					
						
							|  |  |  |     // Compare with actual gradients
 | 
					
						
							|  |  |  |     int variablePosition = 0; | 
					
						
							|  |  |  |     for(GaussianConditional::const_iterator jit = clique->conditional()->begin(); jit != clique->conditional()->end(); ++jit) { | 
					
						
							|  |  |  |       const int dim = clique->conditional()->dim(jit); | 
					
						
							|  |  |  |       Vector actual = clique->gradientContribution().segment(variablePosition, dim); | 
					
						
							|  |  |  |       EXPECT(assert_equal(expectedGradient[*jit], actual)); | 
					
						
							|  |  |  |       variablePosition += dim; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     LONGS_EQUAL(clique->gradientContribution().rows(), variablePosition); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Check gradient
 | 
					
						
							|  |  |  |   VectorValues expectedGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |   gradientAtZero(FactorGraph<JacobianFactor>(isam), expectedGradient); | 
					
						
							|  |  |  |   VectorValues expectedGradient2(gradient(FactorGraph<JacobianFactor>(isam), VectorValues::Zero(expectedGradient))); | 
					
						
							|  |  |  |   VectorValues actualGradient(*allocateVectorValues(isam)); | 
					
						
							|  |  |  |   gradientAtZero(isam, actualGradient); | 
					
						
							|  |  |  |   EXPECT(assert_equal(expectedGradient2, expectedGradient)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(expectedGradient, actualGradient)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-19 02:06:35 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | int main() { TestResult tr; return TestRegistry::runAllTests(tr);} | 
					
						
							|  |  |  | /* ************************************************************************* */ |