| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  |  * @file    testGraph.cpp | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  |  * @brief   Unit test for two cameras and four landmarks | 
					
						
							|  |  |  |  * single camera | 
					
						
							|  |  |  |  * @author  Chris Beall | 
					
						
							|  |  |  |  * @author  Frank Dellaert | 
					
						
							|  |  |  |  * @author  Viorela Ila | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <CppUnitLite/TestHarness.h>
 | 
					
						
							| 
									
										
										
										
											2010-01-12 04:17:28 +08:00
										 |  |  | #include <boost/shared_ptr.hpp>
 | 
					
						
							|  |  |  | using namespace boost; | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 03:34:57 +08:00
										 |  |  | #define GTSAM_MAGIC_KEY
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | #include "NonlinearFactorGraph-inl.h"
 | 
					
						
							|  |  |  | #include "NonlinearOptimizer-inl.h"
 | 
					
						
							| 
									
										
										
										
											2010-01-19 03:11:22 +08:00
										 |  |  | #include "graph-inl.h"
 | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  | #include "visualSLAM.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | using namespace std; | 
					
						
							|  |  |  | using namespace gtsam; | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  | using namespace gtsam::visualSLAM; | 
					
						
							|  |  |  | using namespace boost; | 
					
						
							|  |  |  | typedef NonlinearOptimizer<Graph,Config> Optimizer; | 
					
						
							| 
									
										
										
										
											2010-01-23 01:36:57 +08:00
										 |  |  | static SharedGaussian sigma(noiseModel::Unit::Create(1)); | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2009-11-13 14:19:08 +08:00
										 |  |  | Point3 landmark1(-1.0,-1.0, 0.0); | 
					
						
							|  |  |  | Point3 landmark2(-1.0, 1.0, 0.0); | 
					
						
							|  |  |  | Point3 landmark3( 1.0, 1.0, 0.0); | 
					
						
							|  |  |  | Point3 landmark4( 1.0,-1.0, 0.0); | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 14:19:08 +08:00
										 |  |  | Pose3 camera1(Matrix_(3,3, | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | 		       1., 0., 0., | 
					
						
							|  |  |  | 		       0.,-1., 0., | 
					
						
							|  |  |  | 		       0., 0.,-1. | 
					
						
							|  |  |  | 		       ), | 
					
						
							|  |  |  | 	      Point3(0,0,6.25)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 14:19:08 +08:00
										 |  |  | Pose3 camera2(Matrix_(3,3, | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | 		       1., 0., 0., | 
					
						
							|  |  |  | 		       0.,-1., 0., | 
					
						
							|  |  |  | 		       0., 0.,-1. | 
					
						
							|  |  |  | 		       ), | 
					
						
							|  |  |  | 	      Point3(0,0,5.00)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  | Graph testGraph() { | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  |   Point2 z11(-100, 100); | 
					
						
							| 
									
										
										
										
											2009-11-13 14:19:08 +08:00
										 |  |  | 	Point2 z12(-100,-100); | 
					
						
							|  |  |  | 	Point2 z13( 100,-100); | 
					
						
							|  |  |  | 	Point2 z14( 100, 100); | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | 	Point2 z21(-125, 125); | 
					
						
							| 
									
										
										
										
											2009-11-13 14:19:08 +08:00
										 |  |  | 	Point2 z22(-125,-125); | 
					
						
							|  |  |  | 	Point2 z23( 125,-125); | 
					
						
							|  |  |  | 	Point2 z24( 125, 125); | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-17 18:02:43 +08:00
										 |  |  |   shared_ptrK sK(new Cal3_S2(625, 625, 0, 0, 0)); | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  |   Graph g; | 
					
						
							|  |  |  |   g.add(ProjectionFactor(z11, sigma, 1, 1, sK)); | 
					
						
							|  |  |  |   g.add(ProjectionFactor(z12, sigma, 1, 2, sK)); | 
					
						
							|  |  |  |   g.add(ProjectionFactor(z13, sigma, 1, 3, sK)); | 
					
						
							|  |  |  |   g.add(ProjectionFactor(z14, sigma, 1, 4, sK)); | 
					
						
							|  |  |  |   g.add(ProjectionFactor(z21, sigma, 2, 1, sK)); | 
					
						
							|  |  |  |   g.add(ProjectionFactor(z22, sigma, 2, 2, sK)); | 
					
						
							|  |  |  |   g.add(ProjectionFactor(z23, sigma, 2, 3, sK)); | 
					
						
							|  |  |  |   g.add(ProjectionFactor(z24, sigma, 2, 4, sK)); | 
					
						
							| 
									
										
										
										
											2009-11-18 01:19:54 +08:00
										 |  |  |   return g; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-11-13 14:19:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-18 01:19:54 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  | TEST( Graph, optimizeLM) | 
					
						
							| 
									
										
										
										
											2009-11-18 01:19:54 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   // build a graph
 | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  |   shared_ptr<Graph> graph(new Graph(testGraph())); | 
					
						
							| 
									
										
										
										
											2009-11-13 14:19:08 +08:00
										 |  |  | 	// add 3 landmark constraints
 | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  |   graph->add(PointConstraint(1, landmark1)); | 
					
						
							|  |  |  |   graph->add(PointConstraint(2, landmark2)); | 
					
						
							|  |  |  |   graph->add(PointConstraint(3, landmark3)); | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-18 01:19:54 +08:00
										 |  |  |   // Create an initial configuration corresponding to the ground truth
 | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  |   boost::shared_ptr<Config> initialEstimate(new Config); | 
					
						
							| 
									
										
										
										
											2010-01-14 10:58:29 +08:00
										 |  |  |   initialEstimate->insert(1, camera1); | 
					
						
							|  |  |  |   initialEstimate->insert(2, camera2); | 
					
						
							|  |  |  |   initialEstimate->insert(1, landmark1); | 
					
						
							|  |  |  |   initialEstimate->insert(2, landmark2); | 
					
						
							|  |  |  |   initialEstimate->insert(3, landmark3); | 
					
						
							|  |  |  |   initialEstimate->insert(4, landmark4); | 
					
						
							| 
									
										
										
										
											2009-11-18 01:19:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create an ordering of the variables
 | 
					
						
							| 
									
										
										
										
											2010-01-18 03:34:57 +08:00
										 |  |  |   list<Symbol> keys; | 
					
						
							| 
									
										
										
										
											2009-11-18 01:19:54 +08:00
										 |  |  |   keys.push_back("l1"); | 
					
						
							|  |  |  |   keys.push_back("l2"); | 
					
						
							|  |  |  |   keys.push_back("l3"); | 
					
						
							|  |  |  |   keys.push_back("l4"); | 
					
						
							|  |  |  |   keys.push_back("x1"); | 
					
						
							|  |  |  |   keys.push_back("x2"); | 
					
						
							| 
									
										
										
										
											2010-01-12 04:17:28 +08:00
										 |  |  |   shared_ptr<Ordering> ordering(new Ordering(keys)); | 
					
						
							| 
									
										
										
										
											2009-11-18 01:19:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create an optimizer and check its error
 | 
					
						
							|  |  |  |   // We expect the initial to be zero because config is the ground truth
 | 
					
						
							| 
									
										
										
										
											2010-01-20 10:28:23 +08:00
										 |  |  | 	Optimizer::shared_solver solver(new Optimizer::solver(ordering)); | 
					
						
							|  |  |  |   Optimizer optimizer(graph, initialEstimate, solver); | 
					
						
							| 
									
										
										
										
											2009-11-18 01:19:54 +08:00
										 |  |  |   DOUBLES_EQUAL(0.0, optimizer.error(), 1e-9); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Iterate once, and the config should not have changed because we started
 | 
					
						
							|  |  |  |   // with the ground truth
 | 
					
						
							|  |  |  |   Optimizer afterOneIteration = optimizer.iterate(); | 
					
						
							|  |  |  |   DOUBLES_EQUAL(0.0, optimizer.error(), 1e-9); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // check if correct
 | 
					
						
							|  |  |  |   CHECK(assert_equal(*initialEstimate,*(afterOneIteration.config()))); | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-18 01:19:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  | TEST( Graph, optimizeLM2) | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   // build a graph
 | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  |   shared_ptr<Graph> graph(new Graph(testGraph())); | 
					
						
							| 
									
										
										
										
											2009-11-18 01:19:54 +08:00
										 |  |  | 	// add 2 camera constraints
 | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  |   graph->add(PoseConstraint(1, camera1)); | 
					
						
							|  |  |  |   graph->add(PoseConstraint(2, camera2)); | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 14:19:08 +08:00
										 |  |  |   // Create an initial configuration corresponding to the ground truth
 | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  |   boost::shared_ptr<Config> initialEstimate(new Config); | 
					
						
							| 
									
										
										
										
											2010-01-14 10:58:29 +08:00
										 |  |  |   initialEstimate->insert(1, camera1); | 
					
						
							|  |  |  |   initialEstimate->insert(2, camera2); | 
					
						
							|  |  |  |   initialEstimate->insert(1, landmark1); | 
					
						
							|  |  |  |   initialEstimate->insert(2, landmark2); | 
					
						
							|  |  |  |   initialEstimate->insert(3, landmark3); | 
					
						
							|  |  |  |   initialEstimate->insert(4, landmark4); | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create an ordering of the variables
 | 
					
						
							| 
									
										
										
										
											2010-01-18 03:34:57 +08:00
										 |  |  |   list<Symbol> keys; | 
					
						
							| 
									
										
										
										
											2009-11-18 01:19:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  |   keys.push_back("l1"); | 
					
						
							|  |  |  |   keys.push_back("l2"); | 
					
						
							|  |  |  |   keys.push_back("l3"); | 
					
						
							|  |  |  |   keys.push_back("l4"); | 
					
						
							|  |  |  |   keys.push_back("x1"); | 
					
						
							|  |  |  |   keys.push_back("x2"); | 
					
						
							| 
									
										
										
										
											2010-01-12 04:17:28 +08:00
										 |  |  |   shared_ptr<Ordering> ordering(new Ordering(keys)); | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 14:19:08 +08:00
										 |  |  |   // Create an optimizer and check its error
 | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  |   // We expect the initial to be zero because config is the ground truth
 | 
					
						
							| 
									
										
										
										
											2010-01-20 10:28:23 +08:00
										 |  |  | 	Optimizer::shared_solver solver(new Optimizer::solver(ordering)); | 
					
						
							|  |  |  |   Optimizer optimizer(graph, initialEstimate, solver); | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  |   DOUBLES_EQUAL(0.0, optimizer.error(), 1e-9); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Iterate once, and the config should not have changed because we started
 | 
					
						
							|  |  |  |   // with the ground truth
 | 
					
						
							|  |  |  |   Optimizer afterOneIteration = optimizer.iterate(); | 
					
						
							|  |  |  |   DOUBLES_EQUAL(0.0, optimizer.error(), 1e-9); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // check if correct
 | 
					
						
							| 
									
										
										
										
											2009-11-13 14:19:08 +08:00
										 |  |  |   CHECK(assert_equal(*initialEstimate,*(afterOneIteration.config()))); | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-10 05:22:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  | TEST( Graph, CHECK_ORDERING) | 
					
						
							| 
									
										
										
										
											2009-12-10 05:22:16 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   // build a graph
 | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  |   shared_ptr<Graph> graph(new Graph(testGraph())); | 
					
						
							| 
									
										
										
										
											2009-12-10 05:22:16 +08:00
										 |  |  |   // add 2 camera constraints
 | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  |   graph->add(PoseConstraint(1, camera1)); | 
					
						
							|  |  |  |   graph->add(PoseConstraint(2, camera2)); | 
					
						
							| 
									
										
										
										
											2009-12-10 05:22:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create an initial configuration corresponding to the ground truth
 | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  |   boost::shared_ptr<Config> initialEstimate(new Config); | 
					
						
							| 
									
										
										
										
											2010-01-14 10:58:29 +08:00
										 |  |  |   initialEstimate->insert(1, camera1); | 
					
						
							|  |  |  |   initialEstimate->insert(2, camera2); | 
					
						
							|  |  |  |   initialEstimate->insert(1, landmark1); | 
					
						
							|  |  |  |   initialEstimate->insert(2, landmark2); | 
					
						
							|  |  |  |   initialEstimate->insert(3, landmark3); | 
					
						
							|  |  |  |   initialEstimate->insert(4, landmark4); | 
					
						
							| 
									
										
										
										
											2009-12-10 05:22:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-12 04:17:28 +08:00
										 |  |  |   shared_ptr<Ordering> ordering(new Ordering(graph->getOrdering())); | 
					
						
							| 
									
										
										
										
											2009-12-10 05:22:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create an optimizer and check its error
 | 
					
						
							|  |  |  |   // We expect the initial to be zero because config is the ground truth
 | 
					
						
							| 
									
										
										
										
											2010-01-20 10:28:23 +08:00
										 |  |  | 	Optimizer::shared_solver solver(new Optimizer::solver(ordering)); | 
					
						
							|  |  |  |   Optimizer optimizer(graph, initialEstimate, solver); | 
					
						
							| 
									
										
										
										
											2009-12-10 05:22:16 +08:00
										 |  |  |   DOUBLES_EQUAL(0.0, optimizer.error(), 1e-9); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Iterate once, and the config should not have changed because we started
 | 
					
						
							|  |  |  |   // with the ground truth
 | 
					
						
							|  |  |  |   Optimizer afterOneIteration = optimizer.iterate(); | 
					
						
							|  |  |  |   DOUBLES_EQUAL(0.0, optimizer.error(), 1e-9); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // check if correct
 | 
					
						
							|  |  |  |   CHECK(assert_equal(*initialEstimate,*(afterOneIteration.config()))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 02:54:46 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | int main() { TestResult tr; TestRegistry::runAllTests(tr); return 0;} | 
					
						
							|  |  |  | /* ************************************************************************* */ |