| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  | /* ----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * GTSAM Copyright 2010, Georgia Tech Research Corporation, | 
					
						
							|  |  |  |  * Atlanta, Georgia 30332-0415 | 
					
						
							|  |  |  |  * All Rights Reserved | 
					
						
							|  |  |  |  * Authors: Frank Dellaert, et al. (see THANKS for the full author list) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * See LICENSE for the license information | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2010-10-27 05:12:44 +08:00
										 |  |  |  * @file    vISAMexample.cpp | 
					
						
							|  |  |  |  * @brief   An ISAM example for synthesis sequence | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  |  * single camera | 
					
						
							| 
									
										
										
										
											2010-10-27 05:12:44 +08:00
										 |  |  |  * @author  Duy-Nguyen Ta | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/shared_ptr.hpp>
 | 
					
						
							| 
									
										
										
										
											2011-12-12 11:57:48 +08:00
										 |  |  | #include <boost/foreach.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  | using namespace boost; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 21:18:26 +08:00
										 |  |  | // Magically casts strings like "x3" to a Symbol('x',3) key, see Key.h
 | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  | #define GTSAM_MAGIC_KEY
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-21 07:25:43 +08:00
										 |  |  | #include <gtsam/nonlinear/NonlinearFactorGraph.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/NonlinearOptimizer.h>
 | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  | #include <gtsam/inference/graph-inl.h>
 | 
					
						
							|  |  |  | #include <gtsam/slam/visualSLAM.h>
 | 
					
						
							|  |  |  | #include <gtsam/slam/PriorFactor.h>
 | 
					
						
							| 
									
										
										
										
											2011-11-18 05:20:04 +08:00
										 |  |  | #include <gtsam/nonlinear/NonlinearISAM.h>
 | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "vSLAMutils.h"
 | 
					
						
							|  |  |  | #include "Feature2D.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using namespace std; | 
					
						
							|  |  |  | using namespace gtsam; | 
					
						
							|  |  |  | using namespace gtsam::visualSLAM; | 
					
						
							|  |  |  | using namespace boost; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-22 07:32:51 +08:00
										 |  |  | #define CALIB_FILE          "calib.txt"
 | 
					
						
							|  |  |  | #define LANDMARKS_FILE      "landmarks.txt"
 | 
					
						
							| 
									
										
										
										
											2011-12-12 11:57:48 +08:00
										 |  |  | #define POSES_FILE          "poses.txt"
 | 
					
						
							|  |  |  | #define MEASUREMENTS_FILE    "measurements.txt"
 | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Base data folder
 | 
					
						
							|  |  |  | string g_dataFolder; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Store groundtruth values, read from files
 | 
					
						
							|  |  |  | shared_ptrK g_calib; | 
					
						
							|  |  |  | map<int, Point3> g_landmarks;        // map: <landmark_id, landmark_position>
 | 
					
						
							| 
									
										
										
										
											2011-12-12 11:57:48 +08:00
										 |  |  | map<int, Pose3> g_poses;            // map: <camera_id, pose>
 | 
					
						
							|  |  |  | std::map<int, std::vector<Feature2D> > g_measurements;    // feature sets detected at each frame
 | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Noise models
 | 
					
						
							| 
									
										
										
										
											2011-08-27 05:41:01 +08:00
										 |  |  | SharedNoiseModel measurementSigma(noiseModel::Isotropic::Sigma(2, 5.0f)); | 
					
						
							|  |  |  | SharedNoiseModel poseSigma(noiseModel::Unit::Create(1)); | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  |  * Read all data: calibration file, landmarks, poses, and all features measurements | 
					
						
							|  |  |  |  * Data is stored in global variables, which are used later to simulate incremental updates. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void readAllDataISAM() { | 
					
						
							|  |  |  |   g_calib = readCalibData(g_dataFolder + CALIB_FILE); | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  |   // Read groundtruth landmarks' positions. These will be used later as intial estimates and priors for landmark nodes.
 | 
					
						
							|  |  |  |   g_landmarks = readLandMarks(g_dataFolder + LANDMARKS_FILE); | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  |   // Read groundtruth camera poses. These will be used later as intial estimates for pose nodes.
 | 
					
						
							| 
									
										
										
										
											2011-12-12 11:57:48 +08:00
										 |  |  |   g_poses = readPoses(g_dataFolder, POSES_FILE); | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  |   // Read all 2d measurements. Those will become factors linking their associating pose and the corresponding landmark.
 | 
					
						
							|  |  |  |   g_measurements = readAllMeasurementsISAM(g_dataFolder, MEASUREMENTS_FILE); | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  |  * Setup newFactors and initialValues for each new pose and set of measurements at each frame. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-11-07 03:08:42 +08:00
										 |  |  | void createNewFactors(shared_ptr<Graph>& newFactors, boost::shared_ptr<visualSLAM::Values>& initialValues, | 
					
						
							| 
									
										
										
										
											2011-12-12 11:57:48 +08:00
										 |  |  |     int pose_id, const Pose3& pose, const std::vector<Feature2D>& measurements, SharedNoiseModel measurementSigma, shared_ptrK calib) { | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create a graph of newFactors with new measurements
 | 
					
						
							|  |  |  |   newFactors = shared_ptr<Graph> (new Graph()); | 
					
						
							|  |  |  |   for (size_t i = 0; i < measurements.size(); i++) { | 
					
						
							|  |  |  |     newFactors->addMeasurement( | 
					
						
							|  |  |  |         measurements[i].m_p, | 
					
						
							|  |  |  |         measurementSigma, | 
					
						
							|  |  |  |         pose_id, | 
					
						
							|  |  |  |         measurements[i].m_idLandmark, | 
					
						
							|  |  |  |         calib); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // ... we need priors on the new pose and all new landmarks
 | 
					
						
							|  |  |  |   newFactors->addPosePrior(pose_id, pose, poseSigma); | 
					
						
							|  |  |  |   for (size_t i = 0; i < measurements.size(); i++) { | 
					
						
							|  |  |  |     newFactors->addPointPrior(measurements[i].m_idLandmark, g_landmarks[measurements[i].m_idLandmark]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Create initial values for all nodes in the newFactors
 | 
					
						
							| 
									
										
										
										
											2011-11-07 03:08:42 +08:00
										 |  |  |   initialValues = shared_ptr<visualSLAM::Values> (new visualSLAM::Values()); | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  |   initialValues->insert(pose_id, pose); | 
					
						
							|  |  |  |   for (size_t i = 0; i < measurements.size(); i++) { | 
					
						
							|  |  |  |     initialValues->insert(measurements[i].m_idLandmark, g_landmarks[measurements[i].m_idLandmark]); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  | int main(int argc, char* argv[]) { | 
					
						
							|  |  |  |   if (argc < 2) { | 
					
						
							|  |  |  |     cout << "Usage: vISAMexample <DataFolder>" << endl << endl; | 
					
						
							|  |  |  |     cout << "\tPlease specify <DataFolder>, which contains calibration file, initial\n" | 
					
						
							| 
									
										
										
										
											2010-10-27 04:02:01 +08:00
										 |  |  |       "\tlandmarks, initial poses, and feature data." << endl; | 
					
						
							| 
									
										
										
										
											2011-10-29 06:10:08 +08:00
										 |  |  |     cout << "\tSample folder is in $gtsam_source_folder$/examples/Data/" << endl << endl; | 
					
						
							|  |  |  |     cout << "Example usage: vISAMexample '$gtsam_source_folder$/examples/Data/'" << endl; | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  |     exit(0); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_dataFolder = string(argv[1]) + "/"; | 
					
						
							|  |  |  |   readAllDataISAM(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-12 11:57:48 +08:00
										 |  |  |   // Create a NonlinearISAM which will be relinearized and reordered after every "relinearizeInterval" updates
 | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  |   int relinearizeInterval = 3; | 
					
						
							| 
									
										
										
										
											2011-11-07 03:08:42 +08:00
										 |  |  |   NonlinearISAM<visualSLAM::Values> isam(relinearizeInterval); | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-12 11:57:48 +08:00
										 |  |  |   // At each frame (poseId) with new camera pose and set of associated measurements,
 | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  |   // create a graph of new factors and update ISAM
 | 
					
						
							| 
									
										
										
										
											2011-12-12 11:57:48 +08:00
										 |  |  |   typedef std::map<int, std::vector<Feature2D> > FeatureMap; | 
					
						
							|  |  |  |   BOOST_FOREACH(const FeatureMap::value_type& features, g_measurements) { | 
					
						
							|  |  |  |     const int poseId = features.first; | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  |     shared_ptr<Graph> newFactors; | 
					
						
							| 
									
										
										
										
											2011-11-07 03:08:42 +08:00
										 |  |  |     shared_ptr<visualSLAM::Values> initialValues; | 
					
						
							| 
									
										
										
										
											2011-12-12 11:57:48 +08:00
										 |  |  |     createNewFactors(newFactors, initialValues, poseId, g_poses[poseId], | 
					
						
							|  |  |  |             features.second, measurementSigma, g_calib); | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     isam.update(*newFactors, *initialValues); | 
					
						
							| 
									
										
										
										
											2011-11-07 03:08:42 +08:00
										 |  |  |     visualSLAM::Values currentEstimate = isam.estimate(); | 
					
						
							| 
									
										
										
										
											2010-10-26 23:01:34 +08:00
										 |  |  |     cout << "****************************************************" << endl; | 
					
						
							|  |  |  |     currentEstimate.print("Current estimate: "); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 05:12:44 +08:00
										 |  |  |   return 1; | 
					
						
							| 
									
										
										
										
											2010-10-22 06:51:20 +08:00
										 |  |  | } | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | 
 |